download a copy of 32-bit Python for this purpose. (Contributed by Zachary
Ware in :issue:`30450`.)
+* Support for building ``--without-threads`` is removed.
+ (Contributed by Antoine Pitrou in :issue:`31370`.).
+
Deprecated
==========
#error "Python's source code assumes C's unsigned char is an 8-bit type."
#endif
-#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
+#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
#define _SGI_MP_SOURCE
#endif
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
-#ifdef WITH_THREAD
-
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
PyAPI_FUNC(void) PyEval_InitThreads(void);
#ifndef Py_LIMITED_API
#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
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
);
#ifndef Py_LIMITED_API
-#ifdef WITH_THREAD
PyAPI_FUNC(void) _PyImport_AcquireLock(void);
PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
-#else
-#define _PyImport_AcquireLock()
-#define _PyImport_ReleaseLock() 1
-#endif
PyAPI_FUNC(void) _PyImport_ReInitLock(void);
#include <android/api-level.h>
#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 */
#ifndef Py_LIMITED_API
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
#endif /* !Py_LIMITED_API */
-#ifdef WITH_THREAD
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
#ifndef Py_LIMITED_API
PyAPI_FUNC(void) _PyGILState_Reinit(void);
#endif /* !Py_LIMITED_API */
-#endif
/* 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
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
PyGILState_STATE;
-#ifdef WITH_THREAD
/* Ensure that the current thread is ready to call the Python
C API, regardless of the current state of Python, or of its
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
#endif
-#endif /* #ifdef WITH_THREAD */
/* The implementation of sys._current_frames() Returns a dict mapping
thread id to that thread's current frame.
+++ /dev/null
-"""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
# work for older Pythons. If threads are not part of the build, create a
# mock threading object with threading.local() returning the module namespace.
-try:
- 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:
- threading.local
-
-except AttributeError:
-
- # To fix reloading, force it to create a new context
- # Old contexts have different exceptions in their dicts, making problems.
- if hasattr(threading.current_thread(), '__decimal_context__'):
- del threading.current_thread().__decimal_context__
-
- def setcontext(context):
- """Set this thread's context to context."""
- if context in (DefaultContext, BasicContext, ExtendedContext):
- 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
+import threading
-else:
+local = threading.local()
+if hasattr(local, '__decimal_context__'):
+ del local.__decimal_context__
- local = threading.local()
- if hasattr(local, '__decimal_context__'):
- del local.__decimal_context__
+def getcontext(_local=local):
+ """Returns this thread's 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()
+ 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
- del threading, local # Don't contaminate the namespace
+del threading, local # Don't contaminate the namespace
def localcontext(ctx=None):
"""Return a context manager for a copy of the supplied context
import stat
import sys
# Import _thread instead of threading to reduce startup cost
-try:
- from _thread import allocate_lock as Lock
-except ImportError:
- from _dummy_thread import allocate_lock as Lock
+from _thread import allocate_lock as Lock
if sys.platform in {'win32', 'cygwin'}:
from msvcrt import setmode as _setmode
else:
from datetime import (date as datetime_date,
timedelta as datetime_timedelta,
timezone as datetime_timezone)
-try:
- from _thread import allocate_lock as _thread_allocate_lock
-except ImportError:
- from _dummy_thread import allocate_lock as _thread_allocate_lock
+from _thread import allocate_lock as _thread_allocate_lock
__all__ = []
import os
import warnings
import _compression
-
-try:
- from threading import RLock
-except ImportError:
- from dummy_threading import RLock
+from threading import RLock
from _bz2 import BZ2Compressor, BZ2Decompressor
import unittest, os, errno
+import threading
+
from ctypes import *
from ctypes.util import find_library
-try:
- import threading
-except ImportError:
- threading = None
class Test(unittest.TestCase):
def test_open(self):
self.assertEqual(set_errno(32), errno.ENOENT)
self.assertEqual(get_errno(), 32)
- if threading:
- def _worker():
- set_errno(0)
+ 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)
+ 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()
+ t = threading.Thread(target=_worker)
+ t.start()
+ t.join()
- self.assertEqual(get_errno(), 32)
- set_errno(0)
+ self.assertEqual(get_errno(), 32)
+ set_errno(0)
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
def test_GetLastError(self):
+++ /dev/null
-"""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
from types import MappingProxyType
from weakref import WeakKeyDictionary
from reprlib import recursive_repr
-try:
- 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
+from _thread import RLock
################################################################################
import re
import time
import urllib.parse, urllib.request
-try:
- import threading as _threading
-except ImportError:
- import dummy_threading as _threading
+import threading as _threading
import http.client # only for the default HTTP port
from calendar import timegm
'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory',
'lastResort', 'raiseExceptions']
-try:
- import threading
-except ImportError: #pragma: no cover
- threading = None
+import threading
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
__status__ = "production"
#the lock would already have been acquired - so we need an RLock.
#The same argument applies to Loggers and Manager.loggerDict.
#
-if threading:
- _lock = threading.RLock()
-else: #pragma: no cover
- _lock = None
-
+_lock = threading.RLock()
def _acquireLock():
"""
self.created = ct
self.msecs = (ct - int(ct)) * 1000
self.relativeCreated = (self.created - _startTime) * 1000
- if logThreads and threading:
+ if logThreads:
self.thread = threading.get_ident()
self.threadName = threading.current_thread().name
else: # pragma: no cover
"""
Acquire a thread lock for serializing access to the underlying I/O.
"""
- if threading:
- self.lock = threading.RLock()
- else: #pragma: no cover
- self.lock = None
+ self.lock = threading.RLock()
def acquire(self):
"""
import re
import struct
import sys
+import threading
import traceback
-try:
- import _thread as thread
- import threading
-except ImportError: #pragma: no cover
- thread = None
-
from socketserver import ThreadingTCPServer, StreamRequestHandler
normal. Note that you can return transformed bytes, e.g. by decrypting
the bytes passed in.
"""
- if not thread: #pragma: no cover
- raise NotImplementedError("listen() needs threading to work")
class ConfigStreamHandler(StreamRequestHandler):
"""
import logging, socket, os, pickle, struct, time, re
from stat import ST_DEV, ST_INO, ST_MTIME
import queue
-try:
- import threading
-except ImportError: #pragma: no cover
- threading = None
+import threading
#
# Some constants...
except Exception:
self.handleError(record)
-if threading:
- 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):
- """
- Initialise an instance with the specified queue and
- handlers.
- """
- self.queue = queue
- self.handlers = handlers
- self._thread = None
- self.respect_handler_level = respect_handler_level
-
- def dequeue(self, block):
- """
- Dequeue a record and return it, optionally blocking.
-
- The base implementation uses get. You may want to override this method
- if you want to use timeouts or work with custom queue implementations.
- """
- return self.queue.get(block)
-
- def start(self):
- """
- Start the listener.
-
- This starts up a background thread to monitor the queue for
- LogRecords to process.
- """
- self._thread = t = threading.Thread(target=self._monitor)
- t.daemon = True
- t.start()
-
- def prepare(self , record):
- """
- Prepare a record for handling.
-
- This method just returns the passed-in record. You may want to
- override this method if you need to do any custom marshalling or
- manipulation of the record before passing it to the handlers.
- """
- return record
-
- def handle(self, record):
- """
- Handle a record.
-
- This just loops through the handlers offering them the record
- to handle.
- """
- 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)
-
- def _monitor(self):
- """
- Monitor the queue for records, and ask the handler
- to deal with them.
-
- This method runs on a separate, internal thread.
- The thread will terminate if it sees a sentinel object in the queue.
- """
- q = self.queue
- 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:
+
+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):
+ """
+ Initialise an instance with the specified queue and
+ handlers.
+ """
+ self.queue = queue
+ self.handlers = handlers
+ self._thread = None
+ self.respect_handler_level = respect_handler_level
+
+ def dequeue(self, block):
+ """
+ Dequeue a record and return it, optionally blocking.
+
+ The base implementation uses get. You may want to override this method
+ if you want to use timeouts or work with custom queue implementations.
+ """
+ return self.queue.get(block)
+
+ def start(self):
+ """
+ Start the listener.
+
+ This starts up a background thread to monitor the queue for
+ LogRecords to process.
+ """
+ self._thread = t = threading.Thread(target=self._monitor)
+ t.daemon = True
+ t.start()
+
+ def prepare(self , record):
+ """
+ Prepare a record for handling.
+
+ This method just returns the passed-in record. You may want to
+ override this method if you need to do any custom marshalling or
+ manipulation of the record before passing it to the handlers.
+ """
+ return record
+
+ def handle(self, record):
+ """
+ Handle a record.
+
+ This just loops through the handlers offering them the record
+ to handle.
+ """
+ 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)
+
+ def _monitor(self):
+ """
+ Monitor the queue for records, and ask the handler
+ to deal with them.
+
+ This method runs on a separate, internal thread.
+ The thread will terminate if it sees a sentinel object in the queue.
+ """
+ q = self.queue
+ 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
+
+ def enqueue_sentinel(self):
+ """
+ This is used to enqueue the sentinel record.
+
+ The base implementation uses put_nowait. You may want to override this
+ method if you want to use timeouts or work with custom queue
+ implementations.
+ """
+ self.queue.put_nowait(self._sentinel)
- def enqueue_sentinel(self):
- """
- This is used to enqueue the sentinel record.
-
- The base implementation uses put_nowait. You may want to override this
- method if you want to use timeouts or work with custom queue
- implementations.
- """
- self.queue.put_nowait(self._sentinel)
-
- def stop(self):
- """
- Stop the listener.
-
- 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
- may be some records still left on the queue, which won't be processed.
- """
- self.enqueue_sentinel()
- self._thread.join()
- self._thread = None
+ def stop(self):
+ """
+ Stop the listener.
+
+ 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
+ may be some records still left on the queue, which won't be processed.
+ """
+ self.enqueue_sentinel()
+ self._thread.join()
+ self._thread = None
'''A multi-producer, multi-consumer queue.'''
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
+import threading
from collections import deque
from heapq import heappush, heappop
from time import monotonic as time
import builtins
from itertools import islice
-try:
- from _thread import get_ident
-except ImportError:
- from _dummy_thread import get_ident
+from _thread import get_ident
def recursive_repr(fillvalue='...'):
'Decorator to make a repr function return fillvalue for a recursive call'
import time
import heapq
from collections import namedtuple
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
+import threading
from time import monotonic as _time
__all__ = ["scheduler"]
import selectors
import os
import sys
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
+import threading
from io import BufferedIOBase
from time import monotonic as time
# misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.
+import threading
import unittest
import sqlite3 as sqlite
-try:
- import threading
-except ImportError:
- threading = None
from test.support import TESTFN, unlink
self.assertEqual(results, expected)
-@unittest.skipUnless(threading, 'This test requires threading.')
class ThreadTests(unittest.TestCase):
def setUp(self):
self.con = sqlite.connect(":memory:")
import _posixsubprocess
import select
import selectors
- try:
- import threading
- except ImportError:
- import dummy_threading as threading
+ import threading
# When select or poll has indicated that the file is writable,
# we can write up to _PIPE_BUF bytes without risk of blocking.
import errno as _errno
from random import Random as _Random
import weakref as _weakref
-
-try:
- import _thread
-except ImportError:
- import _dummy_thread as _thread
+import _thread
_allocate_lock = _thread.allocate_lock
_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
"""
import os, sys, time, unittest
+import threading
import test.support as support
-threading = support.import_module('threading')
LONGSLEEP = 2
SHORTSLEEP = 0.5
import os
import queue
import sys
+import threading
import time
import traceback
import types
from test import support
-try:
- import threading
-except ImportError:
- print("Multiprocess option requires thread support")
- sys.exit(2)
from test.libregrtest.runtest import (
runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME,
import shutil
import sys
import sysconfig
+import threading
import warnings
from test import support
-try:
- import threading
-except ImportError:
- threading = None
try:
import _multiprocessing, multiprocessing.process
except ImportError:
# Controlling dangling references to Thread objects can make it easier
# to track reference leaks.
def get_threading__dangling(self):
- if not threading:
- return None
# This copies the weakrefs without making any strong reference
return threading._dangling.copy()
def restore_threading__dangling(self, saved):
- if not threading:
- return
threading._dangling.clear()
threading._dangling.update(saved)
import sys
import sysconfig
import tempfile
+import _thread
+import threading
import time
import types
import unittest
import urllib.error
import warnings
-try:
- import _thread, threading
-except ImportError:
- _thread = None
- threading = None
try:
import multiprocessing.process
except ImportError:
# at the end of a test run.
def threading_setup():
- if _thread:
- return _thread._count(), threading._dangling.copy()
- else:
- return 1, ()
+ return _thread._count(), threading._dangling.copy()
def threading_cleanup(*original_values):
global environment_altered
- if not _thread:
- return
_MAX_COUNT = 100
t0 = time.monotonic()
for count in range(_MAX_COUNT):
ensure that the threads are cleaned up even when the test fails.
If threading is unavailable this function does nothing.
"""
- if not _thread:
- return func
-
@functools.wraps(func)
def decorator(*args):
key = threading_setup()
from test import support
-# If this fails, the test will be skipped.
-thread = support.import_module('_thread')
-
import asynchat
import asyncore
import errno
import socket
import sys
+import _thread as thread
+import threading
import time
import unittest
import unittest.mock
-try:
- import threading
-except ImportError:
- threading = None
HOST = support.HOST
SERVER_QUIT = b'QUIT\n'
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):
- threading.Thread.__init__(self)
- self.event = event
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- 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):
- 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
-
- # remove the SERVER_QUIT message
- self.buffer = self.buffer.replace(SERVER_QUIT, b'')
-
- if self.start_resend_event:
- self.start_resend_event.wait()
-
- # re-send entire set of collected data
- try:
- # this may fail on some tests, such as test_close_when_done,
- # since the client closes the channel when it's done sending
- while self.buffer:
- 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):
+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):
+ threading.Thread.__init__(self)
+ self.event = event
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ 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):
+ 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
+
+ # remove the SERVER_QUIT message
+ self.buffer = self.buffer.replace(SERVER_QUIT, b'')
+
+ if self.start_resend_event:
+ self.start_resend_event.wait()
+
+ # re-send entire set of collected data
+ try:
+ # this may fail on some tests, such as test_close_when_done,
+ # since the client closes the channel when it's done sending
+ while self.buffer:
+ 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
- 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 collect_incoming_data(self, data):
+ self.buffer += data
- def found_terminator(self):
- self.contents.append(self.buffer)
- self.buffer = b""
+ 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
+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):
usepoll = False
import os
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.
import_module('concurrent.futures')
import time
import errno
import struct
+import threading
from test import support
from io import BytesIO
if support.PGO:
raise unittest.SkipTest("test is not helpful for PGO")
-try:
- import threading
-except ImportError:
- threading = None
TIMEOUT = 3
HAS_UNIX_SOCKETS = hasattr(socket, 'AF_UNIX')
def tearDown(self):
asyncore.close_all()
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.reap_threads
def test_send(self):
evt = threading.Event()
self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR))
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.reap_threads
def test_quick_connect(self):
# see: http://bugs.python.org/issue10340
import random
import shutil
import subprocess
+import threading
from test.support import unlink
import _compression
-try:
- import threading
-except ImportError:
- threading = None
# Skip tests if the bz2 module doesn't exist.
bz2 = support.import_module('bz2')
else:
self.fail("1/0 didn't raise an exception")
- @unittest.skipUnless(threading, 'Threading required for this test.')
def testThreading(self):
# Issue #7205: Using a BZ2File from several threads shouldn't deadlock.
data = b"1" * 2**20
with support.start_threads(threads):
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):
self.createTempFile()
linelen = len(self.TEXT_LINES[0])
import sys
import sysconfig
import textwrap
+import threading
import time
import unittest
from test import support
import _posixsubprocess
except ImportError:
_posixsubprocess = None
-try:
- import threading
-except ImportError:
- threading = None
+
# Skip this test if the _testcapi module isn't available.
_testcapi = support.import_module('_testcapi')
self.assertEqual(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):
with support.SuppressCrashReport():
p = subprocess.Popen([sys.executable, "-c",
self.assertIn(b'MemoryError 3 30', out)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class TestPendingCalls(unittest.TestCase):
def pendingcalls_submit(self, l, n):
parse((1,), {}, 'O|OO', ['', 'a', ''])
-@unittest.skipUnless(threading, 'Threading required for this test.')
class TestThreadState(unittest.TestCase):
@support.reap_threads
regex = regex.format(ptr=self.PTR_REGEX)
self.assertRegex(out, regex)
- @unittest.skipUnless(threading, 'Test requires a GIL (multithreading)')
def check_malloc_without_gil(self, code):
out = self.check(code)
expected = ('Fatal Python error: Python memory allocator called '
test.support.import_module('_multiprocessing')
# Skip tests if sem_open implementation is broken.
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
import io
import sys
import tempfile
+import threading
import unittest
from contextlib import * # Tests __all__
from test import support
-try:
- import threading
-except ImportError:
- threading = None
class TestAbstractContextManager(unittest.TestCase):
finally:
support.unlink(tfn)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class LockContextTestCase(unittest.TestCase):
def boilerPlate(self, lock, locked):
run_with_locale, cpython_only)
import random
import inspect
-try:
- import threading
-except ImportError:
- threading = None
+import threading
C = import_fresh_module('decimal', fresh=['_decimal'])
DefaultContext.Emax = save_emax
DefaultContext.Emin = save_emin
-@unittest.skipUnless(threading, 'threading required')
+
class CThreadingTest(ThreadingTest):
decimal = C
-@unittest.skipUnless(threading, 'threading required')
+
class PyThreadingTest(ThreadingTest):
decimal = P
from xmlrpc.server import DocXMLRPCServer
import http.client
import sys
+import threading
from test import support
-threading = support.import_module('threading')
import unittest
def make_request_and_skipIf(condition, reason):
+++ /dev/null
-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)
+++ /dev/null
-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()
from itertools import chain
from random import choice
from socket import getfqdn
-try:
- from threading import Thread
-except ImportError:
- from dummy_threading import Thread
+from threading import Thread
import email
import email.policy
import inspect
import pydoc
import unittest
+import threading
from collections import OrderedDict
from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto
from io import StringIO
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
from test import support
-try:
- import threading
-except ImportError:
- threading = None
# for pickle tests
d = 6
self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.reap_threads
def test_unique_composite(self):
# override __eq__ to be identity only
for f in Open:
self.assertEqual(bool(f.value), bool(f))
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.reap_threads
def test_unique_composite(self):
# override __eq__ to be identity only
from test import support
from test.support import script_helper, is_android, requires_android_level
import tempfile
+import threading
import unittest
from textwrap import dedent
-try:
- import threading
- HAVE_THREADS = True
-except ImportError:
- HAVE_THREADS = False
try:
import _testcapi
except ImportError:
3,
'Segmentation fault')
- @unittest.skipIf(not HAVE_THREADS, 'need threads')
def test_fatal_error_c_thread(self):
self.check_fatal_error("""
import faulthandler
2,
'xyz')
- @unittest.skipIf(sys.platform.startswith('openbsd') and HAVE_THREADS,
+ @unittest.skipIf(sys.platform.startswith('openbsd'),
"Issue #12868: sigaltstack() doesn't work on "
"OpenBSD if Python is compiled with pthread")
@unittest.skipIf(not hasattr(faulthandler, '_stack_overflow'),
self.assertEqual(trace, expected)
self.assertEqual(exitcode, 0)
- @unittest.skipIf(not HAVE_THREADS, 'need threads')
def check_dump_traceback_threads(self, filename):
"""
Call explicitly dump_traceback(all_threads=True) and check the output.
import os
import signal
import sys
+import threading
import time
import unittest
from test.support import (reap_children, get_attribute,
import_module, verbose)
-threading = import_module('threading')
# Skip test if fork does not exist.
get_attribute(os, 'fork')
import io
import errno
import os
+import threading
import time
try:
import ssl
from unittest import TestCase, skipUnless
from test import support
from test.support import HOST, HOSTv6
-threading = support.import_module('threading')
TIMEOUT = 3
# the dummy data returned by server over the data channel when
from random import choice
import sys
from test import support
+import threading
import time
import unittest
import unittest.mock
from weakref import proxy
import contextlib
-try:
- import threading
-except ImportError:
- threading = None
import functools
for attr in self.module.WRAPPER_ASSIGNMENTS:
self.assertEqual(getattr(g, attr), getattr(f, attr))
- @unittest.skipUnless(threading, 'This test requires threading.')
def test_lru_cache_threaded(self):
n, m = 5, 11
def orig(x, y):
finally:
sys.setswitchinterval(orig_si)
- @unittest.skipUnless(threading, 'This test requires threading.')
def test_lru_cache_threaded2(self):
# Simultaneous call with the same arguments
n, m = 5, 7
pause.reset()
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):
@self.module.lru_cache(maxsize=2)
def f(x):
import time
import gc
import weakref
-
-try:
- import threading
-except ImportError:
- threading = None
+import threading
try:
from _testcapi import with_tp_del
v = {1: v, 2: Ouch()}
gc.disable()
- @unittest.skipUnless(threading, "test meaningless on builds without threads")
def test_trashcan_threads(self):
# Issue #13992: trashcan mechanism should be thread-safe
NESTING = 60
import textwrap
import unittest
-# Is this Python configured to support threads?
-try:
- import _thread
-except ImportError:
- _thread = None
-
from test import support
from test.support import run_unittest, findfile, python_is_optimized
foo\(1, 2, 3\)
''')
- @unittest.skipUnless(_thread,
- "Python was compiled without thread support")
def test_threads(self):
'Verify that "py-bt" indicates threads that are waiting for the GIL'
cmd = '''
# Some older versions of gdb will fail with
# "Cannot find new threads: generic error"
# 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):
'Verify that "py-bt" indicates if a thread is garbage-collecting'
cmd = ('from gc import collect\n'
# Some older versions of gdb will fail with
# "Cannot find new threads: generic error"
# 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):
'Verify that "py-bt" displays invocations of PyCFunction instances'
# Tested function must not be defined with METH_NOARGS or METH_O,
import itertools
import os
import sys
-try:
- import threading
-except ImportError:
- threading = None
+import threading
import unittest
import warnings
from test import support
m = hashlib.md5(b'x' * gil_minsize)
self.assertEqual(m.hexdigest(), 'cfb767f225d58469c5de3632a8803958')
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.reap_threads
def test_threaded_hashing(self):
# Updating the same hash object from several threads at once
import tempfile
import time
import datetime
+import threading
from unittest import mock
from io import BytesIO
import unittest
from test import support
-threading = support.import_module('threading')
+
class NoLogRequestHandler:
def log_message(self, *args):
# 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.
-import_module('threading') # imported by PyShell, imports _thread
tk = import_module('tkinter') # imports _tkinter
if tk.TkVersion < 8.5:
raise unittest.SkipTest("IDLE requires tk 8.5 or later.")
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
import imaplib
import socketserver
import time
import calendar
+import threading
from test.support import (reap_threads, verbose, transient_internet,
run_with_tz, run_with_locale, cpython_only)
-try:
- import _thread
-except ImportError:
- _thread = None
import importlib
import importlib.util
import os
'imp.load_dynamic() required')(meth)
-@unittest.skipIf(_thread is None, '_thread module is required')
class LockTests(unittest.TestCase):
"""Very basic test of import lock functions."""
init = test_util.import_importlib('importlib')
import sys
+import threading
import unittest
import weakref
from test import support
-
-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 DeadlockAvoidanceTests:
-
- def setUp(self):
+from test import lock_tests
+
+
+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)
+
+
+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:
- 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
+ lock.acquire()
+ except self.DeadlockError:
+ return False
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:
- lock.acquire()
- except self.DeadlockError:
- return False
- else:
- return True
-
- def f():
- a, b = pairs.pop()
- ra = _acquire(a)
- barrier.wait()
- rb = _acquire(b)
- results.append((ra, rb))
- if rb:
- b.release()
- if ra:
- a.release()
- lock_tests.Bunch(f, NTHREADS).wait_for_finished()
- self.assertEqual(len(results), NTHREADS)
- return results
-
- def test_deadlock(self):
- results = self.run_deadlock_avoidance_test(True)
- # At least one of the threads detected a potential deadlock on its
- # second acquire() call. It may be several of them, because the
- # 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
- for kind, splitinit in init.items()}
-
- (Frozen_DeadlockAvoidanceTests,
- Source_DeadlockAvoidanceTests
- ) = test_util.test_both(DeadlockAvoidanceTests,
- LockType=LOCK_TYPES,
- DeadlockError=DEADLOCK_ERRORS)
-else:
- DEADLOCK_ERRORS = {}
-
- class Frozen_DeadlockAvoidanceTests(unittest.TestCase):
- pass
-
- class Source_DeadlockAvoidanceTests(unittest.TestCase):
- pass
+ return True
+
+ def f():
+ a, b = pairs.pop()
+ ra = _acquire(a)
+ barrier.wait()
+ rb = _acquire(b)
+ results.append((ra, rb))
+ if rb:
+ b.release()
+ if ra:
+ a.release()
+ lock_tests.Bunch(f, NTHREADS).wait_for_finished()
+ self.assertEqual(len(results), NTHREADS)
+ return results
+
+ def test_deadlock(self):
+ results = self.run_deadlock_avoidance_test(True)
+ # At least one of the threads detected a potential deadlock on its
+ # second acquire() call. It may be several of them, because the
+ # 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
+ for kind, splitinit in init.items()}
+
+(Frozen_DeadlockAvoidanceTests,
+ Source_DeadlockAvoidanceTests
+ ) = test_util.test_both(DeadlockAvoidanceTests,
+ LockType=LOCK_TYPES,
+ DeadlockError=DEADLOCK_ERRORS)
class LifetimeTests:
import random
import signal
import sys
+import threading
import time
import unittest
import warnings
import codecs
import io # C implementation of io
import _pyio as pyio # Python implementation of io
-try:
- import threading
-except ImportError:
- threading = None
try:
import ctypes
(self.BytesIO, "rws"), (self.StringIO, "rws"),
)
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:
readable = "r" in abilities
self.assertEqual(obj.readable(), readable)
self.assertEqual(b"abcdefg", bufio.read())
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.requires_resource('cpu')
def test_threads(self):
try:
with self.open(support.TESTFN, "rb", buffering=0) as f:
self.assertEqual(f.read(), b"abc")
- @unittest.skipUnless(threading, 'Threading required for this test.')
@support.requires_resource('cpu')
def test_threads(self):
try:
self.assertEqual(f.errors, "replace")
@support.no_tracing
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_threads_write(self):
# Issue6750: concurrent writes could duplicate data
event = threading.Event()
b = bytearray(2)
self.assertRaises(ValueError, bufio.readinto, b)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def check_daemon_threads_shutdown_deadlock(self, stream_name):
# Issue #23309: deadlocks at shutdown should be avoided when a
# daemon thread and the main thread both write to a file.
def alarm_interrupt(self, sig, frame):
1/0
- @unittest.skipUnless(threading, 'Threading required for this test.')
def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
"""Check that a partial write, when it gets interrupted, properly
invokes the signal handler, and bubbles up the exception raised
self.check_interrupted_read_retry(lambda x: x,
mode="r")
- @unittest.skipUnless(threading, 'Threading required for this test.')
def check_interrupted_write_retry(self, item, **fdopen_kwargs):
"""Check that a buffered write, when it gets interrupted (either
returning a partial result or EINTR), properly invokes the signal
from test.support.script_helper import assert_python_ok
from test import support
import textwrap
+import threading
import time
import unittest
import warnings
import weakref
-try:
- import threading
- # The following imports are needed only for tests which
- # require threading
- import asyncore
- from http.server import HTTPServer, BaseHTTPRequestHandler
- import smtpd
- from urllib.parse import urlparse, parse_qs
- from socketserver import (ThreadingUDPServer, DatagramRequestHandler,
- ThreadingTCPServer, StreamRequestHandler)
-except ImportError:
- threading = None
+
+import asyncore
+from http.server import HTTPServer, BaseHTTPRequestHandler
+import smtpd
+from urllib.parse import urlparse, parse_qs
+from socketserver import (ThreadingUDPServer, DatagramRequestHandler,
+ ThreadingTCPServer, StreamRequestHandler)
+
try:
import win32evtlog, win32evtlogutil, pywintypes
except ImportError:
os.unlink(fn)
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_race(self):
# Issue #14632 refers.
def remove_loop(fname, tries):
# -- 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 threading:
- class TestSMTPServer(smtpd.SMTPServer):
+class TestSMTPServer(smtpd.SMTPServer):
+ """
+ This class implements a test SMTP server.
+
+ :param addr: A (host, port) tuple which the server listens on.
+ You can specify a port value of zero: the server's
+ *port* attribute will hold the actual port number
+ used, which can be used in client connections.
+ :param handler: A callable which will be called to process
+ incoming messages. The handler will be passed
+ the client address tuple, who the message is from,
+ 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.
"""
- This class implements a test SMTP server.
-
- :param addr: A (host, port) tuple which the server listens on.
- You can specify a port value of zero: the server's
- *port* attribute will hold the actual port number
- used, which can be used in client connections.
- :param handler: A callable which will be called to process
- incoming messages. The handler will be passed
- the client address tuple, who the message is from,
- a list of recipients and the message data.
+ 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
: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.
"""
+ 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):
- 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 stop(self, timeout=None):
+ """
+ Stop the thread by closing the server instance.
+ Wait for the server thread to terminate.
- def process_message(self, peer, mailfrom, rcpttos, data):
- """
- Delegates to the handler passed in to the server's constructor.
+ :param timeout: How long to wait for the server thread
+ to terminate.
+ """
+ self.close()
+ self._thread.join(timeout)
+ asyncore.close_all(map=self._map, ignore_all=True)
- 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)
+ alive = self._thread.is_alive()
+ self._thread = None
+ if alive:
+ self.fail("join() timed out")
- 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()
+class ControlMixin(object):
+ """
+ This mixin is used to start a server on a separate thread, and
+ 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
+ single parameter - the request - in order to
+ process the request. This handler is called on the
+ server thread, effectively meaning that requests are
+ processed serially. While not quite Web scale ;-),
+ this should be fine for testing applications.
+ :param poll_interval: The polling interval in seconds.
+ """
+ def __init__(self, handler, poll_interval):
+ self._thread = None
+ self.poll_interval = poll_interval
+ self._handler = handler
+ self.ready = threading.Event()
- 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
- :func:`select` or :func:`poll` call by
- :func:`asyncore.loop`.
- """
- 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 stop(self, timeout=None):
- """
- Stop the thread by closing the server instance.
- Wait for the server thread to terminate.
+ def start(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()
- :param timeout: How long to wait for the server thread
- to terminate.
- """
- self.close()
- self._thread.join(timeout)
- asyncore.close_all(map=self._map, ignore_all=True)
+ def serve_forever(self, poll_interval):
+ """
+ Run the server. Set the ready flag before entering the
+ 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)
alive = self._thread.is_alive()
self._thread = None
if alive:
self.fail("join() timed out")
+ self.server_close()
+ self.ready.clear()
- class ControlMixin(object):
- """
- This mixin is used to start a server on a separate thread, and
- 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
- single parameter - the request - in order to
- process the request. This handler is called on the
- server thread, effectively meaning that requests are
- processed serially. While not quite Web scale ;-),
- this should be fine for testing applications.
- :param poll_interval: The polling interval in seconds.
- """
- def __init__(self, handler, poll_interval):
- self._thread = None
- self.poll_interval = poll_interval
- self._handler = handler
- self.ready = threading.Event()
+class TestHTTPServer(ControlMixin, HTTPServer):
+ """
+ An HTTP server which is controllable using :class:`ControlMixin`.
+
+ :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 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):
+ self.server._handler(self)
+
+ def log_message(self, format, *args):
+ if log:
+ super(DelegatingHTTPRequestHandler,
+ self).log_message(format, *args)
+ HTTPServer.__init__(self, addr, DelegatingHTTPRequestHandler)
+ ControlMixin.__init__(self, handler, poll_interval)
+ self.sslctx = sslctx
+
+ def get_request(self):
+ try:
+ 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
- def start(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()
+class TestTCPServer(ControlMixin, ThreadingTCPServer):
+ """
+ A TCP server which is controllable using :class:`ControlMixin`.
+
+ :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
+ 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.
+ """
- def serve_forever(self, poll_interval):
- """
- Run the server. Set the ready flag before entering the
- service loop.
- """
- self.ready.set()
- super(ControlMixin, self).serve_forever(poll_interval)
+ allow_reuse_address = True
- def stop(self, timeout=None):
- """
- Tell the server thread to stop, and wait for it to do so.
+ def __init__(self, addr, handler, poll_interval=0.5,
+ bind_and_activate=True):
+ class DelegatingTCPRequestHandler(StreamRequestHandler):
- :param timeout: How long to wait for the server thread
- to terminate.
- """
- 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):
- """
- An HTTP server which is controllable using :class:`ControlMixin`.
-
- :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 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):
- self.server._handler(self)
-
- def log_message(self, format, *args):
- if log:
- super(DelegatingHTTPRequestHandler,
- self).log_message(format, *args)
- HTTPServer.__init__(self, addr, DelegatingHTTPRequestHandler)
- ControlMixin.__init__(self, handler, poll_interval)
- self.sslctx = sslctx
-
- def get_request(self):
- try:
- 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
+ def handle(self):
+ self.server._handler(self)
+ ThreadingTCPServer.__init__(self, addr, DelegatingTCPRequestHandler,
+ bind_and_activate)
+ ControlMixin.__init__(self, handler, poll_interval)
- class TestTCPServer(ControlMixin, ThreadingTCPServer):
- """
- A TCP server which is controllable using :class:`ControlMixin`.
-
- :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
- 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.
- """
+ def server_bind(self):
+ super(TestTCPServer, self).server_bind()
+ self.port = self.socket.getsockname()[1]
- allow_reuse_address = True
+class TestUDPServer(ControlMixin, ThreadingUDPServer):
+ """
+ A UDP server which is controllable using :class:`ControlMixin`.
+
+ :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 parameter - the request - in order to
+ 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 __init__(self, addr, handler, poll_interval=0.5,
- bind_and_activate=True):
- class DelegatingTCPRequestHandler(StreamRequestHandler):
+ def handle(self):
+ self.server._handler(self)
- def handle(self):
- self.server._handler(self)
- ThreadingTCPServer.__init__(self, addr, DelegatingTCPRequestHandler,
- bind_and_activate)
- ControlMixin.__init__(self, handler, poll_interval)
+ def finish(self):
+ data = self.wfile.getvalue()
+ if data:
+ try:
+ super(DelegatingUDPRequestHandler, self).finish()
+ except OSError:
+ if not self.server._closed:
+ raise
- def server_bind(self):
- super(TestTCPServer, self).server_bind()
- self.port = self.socket.getsockname()[1]
+ ThreadingUDPServer.__init__(self, addr,
+ DelegatingUDPRequestHandler,
+ bind_and_activate)
+ ControlMixin.__init__(self, handler, poll_interval)
+ self._closed = False
- class TestUDPServer(ControlMixin, ThreadingUDPServer):
- """
- A UDP server which is controllable using :class:`ControlMixin`.
-
- :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 parameter - the request - in order to
- 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):
- self.server._handler(self)
-
- 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
+ def server_bind(self):
+ super(TestUDPServer, self).server_bind()
+ self.port = self.socket.getsockname()[1]
- if hasattr(socket, "AF_UNIX"):
- class TestUnixStreamServer(TestTCPServer):
- address_family = socket.AF_UNIX
+ def server_close(self):
+ super(TestUDPServer, self).server_close()
+ self._closed = True
- class TestUnixDatagramServer(TestUDPServer):
- address_family = socket.AF_UNIX
+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
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SMTPHandlerTest(BaseTest):
TIMEOUT = 8.0
@unittest.skipIf(True, "FIXME: bpo-30830")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SocketHandlerTest(BaseTest):
"""Test for SocketHandler objects."""
- if threading:
- server_class = TestTCPServer
- address = ('localhost', 0)
+ server_class = TestTCPServer
+ address = ('localhost', 0)
def setUp(self):
"""Set up a TCP server to receive log messages, and a SocketHandler
@unittest.skipIf(True, "FIXME: bpo-30830")
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixSocketHandlerTest(SocketHandlerTest):
"""Test for SocketHandler with unix sockets."""
- if threading and hasattr(socket, "AF_UNIX"):
+ if hasattr(socket, "AF_UNIX"):
server_class = TestUnixStreamServer
def setUp(self):
support.unlink(self.address)
@unittest.skipIf(True, "FIXME: bpo-30830")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class DatagramHandlerTest(BaseTest):
"""Test for DatagramHandler."""
- if threading:
- server_class = TestUDPServer
- address = ('localhost', 0)
+ server_class = TestUDPServer
+ address = ('localhost', 0)
def setUp(self):
"""Set up a UDP server to receive log messages, and a DatagramHandler
@unittest.skipIf(True, "FIXME: bpo-30830")
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixDatagramHandlerTest(DatagramHandlerTest):
"""Test for DatagramHandler using Unix sockets."""
- if threading and hasattr(socket, "AF_UNIX"):
+ if hasattr(socket, "AF_UNIX"):
server_class = TestUnixDatagramServer
def setUp(self):
DatagramHandlerTest.tearDown(self)
support.unlink(self.address)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SysLogHandlerTest(BaseTest):
"""Test for SysLogHandler using UDP."""
- if threading:
- server_class = TestUDPServer
- address = ('localhost', 0)
+ server_class = TestUDPServer
+ address = ('localhost', 0)
def setUp(self):
"""Set up a UDP server to receive log messages, and a SysLogHandler
@unittest.skipIf(True, "FIXME: bpo-30830")
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class UnixSysLogHandlerTest(SysLogHandlerTest):
"""Test for SysLogHandler with Unix sockets."""
- if threading and hasattr(socket, "AF_UNIX"):
+ if hasattr(socket, "AF_UNIX"):
server_class = TestUnixDatagramServer
def setUp(self):
@unittest.skipIf(True, "FIXME: bpo-30830")
@unittest.skipUnless(support.IPV6_ENABLED,
'IPv6 support required for this test.')
-@unittest.skipUnless(threading, 'Threading required for this test.')
class IPv6SysLogHandlerTest(SysLogHandlerTest):
"""Test for SysLogHandler with IPv6 host."""
self.server_class.address_family = socket.AF_INET
super(IPv6SysLogHandlerTest, self).tearDown()
-@unittest.skipUnless(threading, 'Threading required for this test.')
class HTTPHandlerTest(BaseTest):
"""Test for HTTPHandler."""
# listen() uses ConfigSocketReceiver which is based
# on socketserver.ThreadingTCPServer
@unittest.skipIf(True, "FIXME: bpo-30830")
- @unittest.skipUnless(threading, 'listen() needs threading to work')
def setup_via_listener(self, text, verify=None):
text = text.encode("utf-8")
# Ask for a randomly assigned port (by using port 0)
if t.is_alive():
self.fail("join() timed out")
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_listen_config_10_ok(self):
with support.captured_stdout() as output:
self.setup_via_listener(json.dumps(self.config10))
('ERROR', '4'),
], stream=output)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_listen_config_1_ok(self):
with support.captured_stdout() as output:
self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1))
# Original logger output is empty.
self.assert_log_lines([])
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_listen_verify(self):
def verify_fail(stuff):
def test_optional(self):
r = logging.makeLogRecord({})
NOT_NONE = self.assertIsNotNone
- if threading:
- NOT_NONE(r.thread)
- NOT_NONE(r.threadName)
+ NOT_NONE(r.thread)
+ NOT_NONE(r.threadName)
NOT_NONE(r.process)
NOT_NONE(r.processName)
log_threads = logging.logThreads
import functools
import contextlib
import os.path
+import threading
+
from test import support
from nntplib import NNTP, GroupInfo
import nntplib
import ssl
except ImportError:
ssl = None
-try:
- import threading
-except ImportError:
- threading = None
+
TIMEOUT = 30
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
def nntp_class(*pos, **kw):
return nntplib.NNTP_SSL(*pos, ssl_context=bypass_context, **kw)
-@unittest.skipUnless(threading, 'requires multithreading')
+
class LocalServerTests(unittest.TestCase):
def setUp(self):
sock = socket.socket()
import subprocess
import sys
import sysconfig
+import threading
import time
import unittest
import uuid
import warnings
from test import support
-try:
- import threading
-except ImportError:
- threading = None
+
try:
import resource
except ImportError:
raise
-if threading is not None:
- class SendfileTestServer(asyncore.dispatcher, threading.Thread):
-
- class Handler(asynchat.async_chat):
+class SendfileTestServer(asyncore.dispatcher, threading.Thread):
- def __init__(self, conn):
- asynchat.async_chat.__init__(self, conn)
- self.in_buffer = []
- self.closed = False
- self.push(b"220 ready\r\n")
+ class Handler(asynchat.async_chat):
- def handle_read(self):
- data = self.recv(4096)
- self.in_buffer.append(data)
+ def __init__(self, conn):
+ asynchat.async_chat.__init__(self, conn)
+ self.in_buffer = []
+ self.closed = False
+ self.push(b"220 ready\r\n")
- def get_data(self):
- return b''.join(self.in_buffer)
+ def handle_read(self):
+ data = self.recv(4096)
+ self.in_buffer.append(data)
- def handle_close(self):
- self.close()
- self.closed = True
+ def get_data(self):
+ return b''.join(self.in_buffer)
- 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):
+ def handle_close(self):
self.close()
- handle_read = handle_connect
-
- def writable(self):
- return 0
+ 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()
+ 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()")
class TestSendfile(unittest.TestCase):
# invoking "continue" on a non-main thread triggered an exception
# inside signal.signal
- # raises SkipTest if python was built without threads
- support.import_module('threading')
-
with open(support.TESTFN, 'wb') as f:
f.write(textwrap.dedent("""
import threading
import subprocess
import random
import select
-try:
- import threading
-except ImportError:
- threading = None
+import threading
import time
import unittest
from test.support import TESTFN, run_unittest, reap_threads, cpython_only
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)
- @unittest.skipUnless(threading, 'Threading required for this test.')
@reap_threads
def test_threaded_poll(self):
r, w = os.pipe()
import socket
import os
import errno
+import threading
from unittest import TestCase, skipUnless
from test import support as test_support
-threading = test_support.import_module('threading')
HOST = test_support.HOST
PORT = 0
import xml.etree
import xml.etree.ElementTree
import textwrap
+import threading
from io import StringIO
from collections import namedtuple
from test.support.script_helper import assert_python_ok
)
from test import pydoc_mod
-try:
- import threading
-except ImportError:
- threading = None
class nonascii:
'Це не латиниця'
"stat(path, *, dir_fd=None, follow_symlinks=True)")
-@unittest.skipUnless(threading, 'Threading required for this test.')
class PydocServerTest(unittest.TestCase):
"""Tests for pydoc._start_server"""
# Some simple queue module tests, plus some failure conditions
# to ensure the Queue locks remain stable.
import queue
+import threading
import time
import unittest
from test import support
-threading = support.import_module('threading')
+
QUEUE_SIZE = 5
import sysconfig
import tempfile
import textwrap
+import threading
import unittest
from test import libregrtest
from test import support
code = TEST_INTERRUPTED
test = self.create_test("sigint", code=code)
- try:
- import threading
- tests = (False, True)
- except ImportError:
- tests = (False,)
- for multiprocessing in tests:
+ for multiprocessing in (False, True):
if multiprocessing:
args = ("--slowest", "-j2", test)
else:
import io
import os
+import threading
import unittest
import urllib.robotparser
from collections import namedtuple
from test import support
from http.server import BaseHTTPRequestHandler, HTTPServer
-try:
- import threading
-except ImportError:
- threading = None
class BaseRobotTest:
pass
-@unittest.skipUnless(threading, 'threading required for this test')
class PasswordProtectedSiteTestCase(unittest.TestCase):
def setUp(self):
import queue
import sched
+import threading
import time
import unittest
-try:
- import threading
-except ImportError:
- threading = None
+
TIMEOUT = 10
scheduler.run()
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):
q = queue.Queue()
fun = q.put
scheduler.run()
self.assertEqual(l, [0.02, 0.03, 0.04])
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_cancel_concurrent(self):
q = queue.Queue()
fun = q.put
import statistics
import subprocess
import sys
+import threading
import time
import unittest
from test import support
from test.support.script_helper import assert_python_ok, spawn_python
-try:
- import threading
-except ImportError:
- threading = None
try:
import _testcapi
except ImportError:
class GenericTests(unittest.TestCase):
- @unittest.skipIf(threading is None, "test needs threading module")
def test_enums(self):
for name in dir(signal):
sig = getattr(signal, name)
'need signal.sigwait()')
@unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
'need signal.pthread_sigmask()')
- @unittest.skipIf(threading is None, "test needs threading module")
def test_sigwait_thread(self):
# Check that calling sigwait() from a thread doesn't suspend the whole
# process. A new interpreter is spawned to avoid problems when mixing
import select
import errno
import textwrap
+import threading
import unittest
from test import support, mock_socket
-try:
- import threading
-except ImportError:
- threading = None
HOST = support.HOST
# test server times out, causing the test to fail.
# Test behavior of smtpd.DebuggingServer
-@unittest.skipUnless(threading, 'Threading required for this test.')
class DebuggingServerTests(unittest.TestCase):
maxDiff = None
# test response of client to a non-successful HELO message
-@unittest.skipUnless(threading, 'Threading required for this test.')
class BadHELOServerTests(unittest.TestCase):
def setUp(self):
HOST, self.port, 'localhost', 3)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class TooLongLineTests(unittest.TestCase):
respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n'
# Test various SMTP & ESMTP commands/behaviors that require a simulated server
# (i.e., something with more features than DebuggingServer)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SMTPSimTests(unittest.TestCase):
def setUp(self):
self.last_rcpt_options = rcpt_options
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SMTPUTF8SimTests(unittest.TestCase):
maxDiff = None
channel_class = SimSMTPAUTHInitialResponseChannel
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SMTPAUTHInitialResponseSimTests(unittest.TestCase):
def setUp(self):
self.real_getfqdn = socket.getfqdn
import struct
import random
import string
+import _thread as thread
+import threading
try:
import multiprocessing
except ImportError:
VSOCKPORT = 1234
-try:
- import _thread as thread
- import threading
-except ImportError:
- thread = None
- threading = None
try:
import _socket
except ImportError:
with a recursive lock.
"""
- if threading:
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._cleanup_lock = threading.RLock()
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self._cleanup_lock = threading.RLock()
- def addCleanup(self, *args, **kwargs):
- with self._cleanup_lock:
- return super().addCleanup(*args, **kwargs)
+ def addCleanup(self, *args, **kwargs):
+ with self._cleanup_lock:
+ return super().addCleanup(*args, **kwargs)
- def doCleanups(self, *args, **kwargs):
- with self._cleanup_lock:
- return super().doCleanups(*args, **kwargs)
+ def doCleanups(self, *args, **kwargs):
+ with self._cleanup_lock:
+ return super().doCleanups(*args, **kwargs)
class SocketCANTest(unittest.TestCase):
ThreadableTest.clientTearDown(self)
@unittest.skipIf(fcntl is None, "need fcntl")
-@unittest.skipUnless(thread, 'Threading required for this test.')
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
'VSOCK sockets required for this test.')
@unittest.skipUnless(get_cid() != 2,
@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.')
-@unittest.skipUnless(thread, 'Threading required for this test.')
class CANTest(ThreadedCANSocketTest):
def __init__(self, methodName='runTest'):
@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.')
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RDSTest(ThreadedRDSSocketTest):
def __init__(self, methodName='runTest'):
s.getsockopt(socket.AF_VSOCK,
socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE))
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class BasicTCPTest(SocketConnectedTest):
def __init__(self, methodName='runTest'):
def _testDetach(self):
self.serv_conn.send(MSG)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class BasicUDPTest(ThreadedUDPSocketTest):
def __init__(self, methodName='runTest'):
pass
@requireAttrs(socket.socket, "sendmsg")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendmsgUDPTest(SendmsgConnectionlessTests, SendrecvmsgUDPTestBase):
pass
@requireAttrs(socket.socket, "recvmsg")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgUDPTest(RecvmsgTests, SendrecvmsgUDPTestBase):
pass
@requireAttrs(socket.socket, "recvmsg_into")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoUDPTest(RecvmsgIntoTests, SendrecvmsgUDPTestBase):
pass
@requireAttrs(socket.socket, "sendmsg")
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
@requireSocket("AF_INET6", "SOCK_DGRAM")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendmsgUDP6Test(SendmsgConnectionlessTests, SendrecvmsgUDP6TestBase):
pass
@requireAttrs(socket.socket, "recvmsg")
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
@requireSocket("AF_INET6", "SOCK_DGRAM")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgUDP6Test(RecvmsgTests, SendrecvmsgUDP6TestBase):
pass
@requireAttrs(socket.socket, "recvmsg_into")
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
@requireSocket("AF_INET6", "SOCK_DGRAM")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoUDP6Test(RecvmsgIntoTests, SendrecvmsgUDP6TestBase):
pass
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
@requireAttrs(socket, "IPPROTO_IPV6")
@requireSocket("AF_INET6", "SOCK_DGRAM")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgRFC3542AncillaryUDP6Test(RFC3542AncillaryTest,
SendrecvmsgUDP6TestBase):
pass
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
@requireAttrs(socket, "IPPROTO_IPV6")
@requireSocket("AF_INET6", "SOCK_DGRAM")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoRFC3542AncillaryUDP6Test(RecvmsgIntoMixin,
RFC3542AncillaryTest,
SendrecvmsgUDP6TestBase):
pass
@requireAttrs(socket.socket, "sendmsg")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendmsgTCPTest(SendmsgStreamTests, SendrecvmsgTCPTestBase):
pass
@requireAttrs(socket.socket, "recvmsg")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgTCPTest(RecvmsgTests, RecvmsgGenericStreamTests,
SendrecvmsgTCPTestBase):
pass
@requireAttrs(socket.socket, "recvmsg_into")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoTCPTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
SendrecvmsgTCPTestBase):
pass
@requireAttrs(socket.socket, "sendmsg")
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendmsgSCTPStreamTest(SendmsgStreamTests, SendrecvmsgSCTPStreamTestBase):
pass
@requireAttrs(socket.socket, "recvmsg")
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgSCTPStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
SendrecvmsgSCTPStreamTestBase):
@requireAttrs(socket.socket, "recvmsg_into")
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoSCTPStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
SendrecvmsgSCTPStreamTestBase):
@requireAttrs(socket.socket, "sendmsg")
@requireAttrs(socket, "AF_UNIX")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendmsgUnixStreamTest(SendmsgStreamTests, SendrecvmsgUnixStreamTestBase):
pass
@requireAttrs(socket.socket, "recvmsg")
@requireAttrs(socket, "AF_UNIX")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgUnixStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
SendrecvmsgUnixStreamTestBase):
pass
@requireAttrs(socket.socket, "recvmsg_into")
@requireAttrs(socket, "AF_UNIX")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoUnixStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
SendrecvmsgUnixStreamTestBase):
pass
@requireAttrs(socket.socket, "sendmsg", "recvmsg")
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgSCMRightsStreamTest(SCMRightsTest, SendrecvmsgUnixStreamTestBase):
pass
@requireAttrs(socket.socket, "sendmsg", "recvmsg_into")
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class RecvmsgIntoSCMRightsStreamTest(RecvmsgIntoMixin, SCMRightsTest,
SendrecvmsgUnixStreamTestBase):
pass
@requireAttrs(signal, "siginterrupt")
@unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"),
"Don't have signal.alarm or signal.setitimer")
-@unittest.skipUnless(thread, 'Threading required for this test.')
class InterruptedSendTimeoutTest(InterruptedTimeoutBase,
ThreadSafeCleanupTestCase,
SocketListeningTestMixin, TCPTestBase):
self.checkInterruptedSend(self.serv_conn.sendmsg, [b"a"*512])
-@unittest.skipUnless(thread, 'Threading required for this test.')
class TCPCloserTest(ThreadedTCPSocketTest):
def testClose(self):
self.cli.connect((HOST, self.port))
time.sleep(1.0)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class BasicSocketPairTest(SocketPairTest):
def __init__(self, methodName='runTest'):
msg = self.cli.recv(1024)
self.assertEqual(msg, MSG)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class NonBlockingTCPTests(ThreadedTCPSocketTest):
def __init__(self, methodName='runTest'):
time.sleep(0.1)
self.cli.send(MSG)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class FileObjectClassTestCase(SocketConnectedTest):
"""Unit tests for the object returned by socket.makefile()
socket.create_connection((HOST, 1234))
-@unittest.skipUnless(thread, 'Threading required for this test.')
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
def __init__(self, methodName='runTest'):
self.addCleanup(self.cli.close)
self.assertEqual(self.cli.gettimeout(), 30)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest):
def __init__(self, methodName='runTest'):
self.addCleanup(support.unlink, path)
self.assertEqual(self.sock.getsockname(), path)
-@unittest.skipUnless(thread, 'Threading required for this test.')
+
class BufferIOTest(SocketConnectedTest):
"""
Test the buffer versions of socket.recv() and socket.send().
self.cli.close()
-@unittest.skipUnless(thread, 'Threading required for this test.')
class ContextManagersTest(ThreadedTCPSocketTest):
def _testSocketClass(self):
source.close()
-@unittest.skipUnless(thread, 'Threading required for this test.')
class SendfileUsingSendTest(ThreadedTCPSocketTest):
"""
Test the send() implementation of socket.sendfile().
meth, file, count=-1)
-@unittest.skipUnless(thread, 'Threading required for this test.')
@unittest.skipUnless(hasattr(os, "sendfile"),
'os.sendfile() required for this test.')
class SendfileUsingSendfileTest(SendfileUsingSendTest):
import signal
import socket
import tempfile
+import threading
import unittest
import socketserver
import test.support
from test.support import reap_children, reap_threads, verbose
-try:
- import threading
-except ImportError:
- threading = None
+
test.support.requires("network")
testcase.assertEqual(72 << 8, status)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class SocketServerTest(unittest.TestCase):
"""Test all socket servers."""
BaseErrorTestServer(SystemExit)
self.check_result(handled=False)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_threading_handled(self):
ThreadingErrorTestServer(ValueError)
self.check_result(handled=True)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_threading_not_handled(self):
ThreadingErrorTestServer(SystemExit)
self.check_result(handled=False)
self.assertIsInstance(server.wfile, io.BufferedIOBase)
self.assertEqual(server.wfile_fileno, server.request_fileno)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_write(self):
# Test that wfile.write() sends data immediately, and that it does
# not truncate sends when interrupted by a Unix signal
import errno
import pprint
import urllib.request
+import threading
import traceback
import asyncore
import weakref
ssl = support.import_module("ssl")
-try:
- import threading
-except ImportError:
- _have_threads = False
-else:
- _have_threads = True
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
HOST = support.HOST
self.assertRaises(TypeError, bio.write, 1)
-@unittest.skipUnless(_have_threads, "Needs threading module")
class SimpleBackgroundTests(unittest.TestCase):
"""Tests that connect to a simple server running in the background"""
test.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
-if _have_threads:
- from test.ssl_servers import make_https_server
+from test.ssl_servers import make_https_server
- class ThreadedEchoServer(threading.Thread):
+class ThreadedEchoServer(threading.Thread):
- class ConnectionHandler(threading.Thread):
+ class ConnectionHandler(threading.Thread):
- """A mildly complicated class, because we want it to work both
- with and without the SSL wrapper around the socket connection, so
- that we can test the STARTTLS functionality."""
+ """A mildly complicated class, because we want it to work both
+ with and without the SSL wrapper around the socket connection, so
+ that we can test the STARTTLS functionality."""
- def __init__(self, server, connsock, addr):
- self.server = server
+ def __init__(self, server, connsock, addr):
+ self.server = server
+ self.running = False
+ self.sock = connsock
+ self.addr = addr
+ self.sock.setblocking(1)
+ self.sslconn = None
+ threading.Thread.__init__(self)
+ self.daemon = True
+
+ def wrap_conn(self):
+ try:
+ self.sslconn = self.server.context.wrap_socket(
+ self.sock, server_side=True)
+ self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
+ self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
+ except (ssl.SSLError, ConnectionResetError, OSError) as e:
+ # We treat ConnectionResetError as though it were an
+ # SSLError - OpenSSL on Ubuntu abruptly closes the
+ # connection when asked to use an unsupported protocol.
+ #
+ # OSError may occur with wrong protocols, e.g. both
+ # sides use PROTOCOL_TLS_SERVER.
+ #
+ # XXX Various errors can have happened here, for example
+ # a mismatching protocol version, an invalid certificate,
+ # or a low-level bug. This should be made more discriminating.
+ #
+ # bpo-31323: Store the exception as string to prevent
+ # a reference leak: server -> conn_errors -> exception
+ # -> traceback -> self (ConnectionHandler) -> server
+ self.server.conn_errors.append(str(e))
+ if self.server.chatty:
+ handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
self.running = False
- self.sock = connsock
- self.addr = addr
- self.sock.setblocking(1)
- self.sslconn = None
- threading.Thread.__init__(self)
- self.daemon = True
-
- def wrap_conn(self):
- try:
- self.sslconn = self.server.context.wrap_socket(
- self.sock, server_side=True)
- self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
- self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
- except (ssl.SSLError, ConnectionResetError, OSError) as e:
- # We treat ConnectionResetError as though it were an
- # SSLError - OpenSSL on Ubuntu abruptly closes the
- # connection when asked to use an unsupported protocol.
- #
- # OSError may occur with wrong protocols, e.g. both
- # sides use PROTOCOL_TLS_SERVER.
- #
- # XXX Various errors can have happened here, for example
- # a mismatching protocol version, an invalid certificate,
- # or a low-level bug. This should be made more discriminating.
- #
- # bpo-31323: Store the exception as string to prevent
- # a reference leak: server -> conn_errors -> exception
- # -> traceback -> self (ConnectionHandler) -> server
- self.server.conn_errors.append(str(e))
- if self.server.chatty:
- handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
- self.running = False
- self.server.stop()
- self.close()
- return False
- else:
- self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
- if self.server.context.verify_mode == ssl.CERT_REQUIRED:
- cert = self.sslconn.getpeercert()
- if support.verbose and self.server.chatty:
- sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
- cert_binary = self.sslconn.getpeercert(True)
- if support.verbose and self.server.chatty:
- sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
- cipher = self.sslconn.cipher()
+ self.server.stop()
+ self.close()
+ return False
+ else:
+ self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
+ if self.server.context.verify_mode == ssl.CERT_REQUIRED:
+ cert = self.sslconn.getpeercert()
if support.verbose and self.server.chatty:
- sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
- sys.stdout.write(" server: selected protocol is now "
- + str(self.sslconn.selected_npn_protocol()) + "\n")
- return True
-
- def read(self):
- if self.sslconn:
- return self.sslconn.read()
- else:
- return self.sock.recv(1024)
+ sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
+ cert_binary = self.sslconn.getpeercert(True)
+ if support.verbose and self.server.chatty:
+ sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
+ cipher = self.sslconn.cipher()
+ if support.verbose and self.server.chatty:
+ sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
+ sys.stdout.write(" server: selected protocol is now "
+ + str(self.sslconn.selected_npn_protocol()) + "\n")
+ return True
+
+ def read(self):
+ if self.sslconn:
+ return self.sslconn.read()
+ else:
+ return self.sock.recv(1024)
- def write(self, bytes):
- if self.sslconn:
- return self.sslconn.write(bytes)
- else:
- return self.sock.send(bytes)
+ def write(self, bytes):
+ if self.sslconn:
+ return self.sslconn.write(bytes)
+ else:
+ return self.sock.send(bytes)
- def close(self):
- if self.sslconn:
- self.sslconn.close()
- else:
- self.sock.close()
+ def close(self):
+ if self.sslconn:
+ self.sslconn.close()
+ else:
+ self.sock.close()
- def run(self):
- self.running = True
- if not self.server.starttls_server:
- if not self.wrap_conn():
- return
- while self.running:
- try:
- msg = self.read()
- stripped = msg.strip()
- if not stripped:
- # eof, so quit this handler
- self.running = False
- try:
- self.sock = self.sslconn.unwrap()
- except OSError:
- # Many tests shut the TCP connection down
- # without an SSL shutdown. This causes
- # unwrap() to raise OSError with errno=0!
- pass
- else:
- self.sslconn = None
- self.close()
- elif stripped == b'over':
- if support.verbose and self.server.connectionchatty:
- sys.stdout.write(" server: client closed connection\n")
- self.close()
- return
- elif (self.server.starttls_server and
- stripped == b'STARTTLS'):
- if support.verbose and self.server.connectionchatty:
- sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
- self.write(b"OK\n")
- if not self.wrap_conn():
- return
- elif (self.server.starttls_server and self.sslconn
- and stripped == b'ENDTLS'):
- if support.verbose and self.server.connectionchatty:
- sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
- self.write(b"OK\n")
+ def run(self):
+ self.running = True
+ if not self.server.starttls_server:
+ if not self.wrap_conn():
+ return
+ while self.running:
+ try:
+ msg = self.read()
+ stripped = msg.strip()
+ if not stripped:
+ # eof, so quit this handler
+ self.running = False
+ try:
self.sock = self.sslconn.unwrap()
- self.sslconn = None
- if support.verbose and self.server.connectionchatty:
- sys.stdout.write(" server: connection is now unencrypted...\n")
- elif stripped == b'CB tls-unique':
- if support.verbose and self.server.connectionchatty:
- sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
- data = self.sslconn.get_channel_binding("tls-unique")
- self.write(repr(data).encode("us-ascii") + b"\n")
+ except OSError:
+ # Many tests shut the TCP connection down
+ # without an SSL shutdown. This causes
+ # unwrap() to raise OSError with errno=0!
+ pass
else:
- if (support.verbose and
- self.server.connectionchatty):
- ctype = (self.sslconn and "encrypted") or "unencrypted"
- sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
- % (msg, ctype, msg.lower(), ctype))
- self.write(msg.lower())
- except OSError:
- if self.server.chatty:
- handle_error("Test server failure:\n")
+ self.sslconn = None
self.close()
- self.running = False
- # normally, we'd just stop here, but for the test
- # harness, we want to stop the server
- self.server.stop()
-
- def __init__(self, certificate=None, ssl_version=None,
- certreqs=None, cacerts=None,
- chatty=True, connectionchatty=False, starttls_server=False,
- npn_protocols=None, alpn_protocols=None,
- ciphers=None, context=None):
- if context:
- self.context = context
- else:
- self.context = ssl.SSLContext(ssl_version
- if ssl_version is not None
- else ssl.PROTOCOL_TLSv1)
- self.context.verify_mode = (certreqs if certreqs is not None
- else ssl.CERT_NONE)
- if cacerts:
- self.context.load_verify_locations(cacerts)
- if certificate:
- self.context.load_cert_chain(certificate)
- if npn_protocols:
- self.context.set_npn_protocols(npn_protocols)
- if alpn_protocols:
- self.context.set_alpn_protocols(alpn_protocols)
- if ciphers:
- self.context.set_ciphers(ciphers)
- self.chatty = chatty
- self.connectionchatty = connectionchatty
- self.starttls_server = starttls_server
- self.sock = socket.socket()
- self.port = support.bind_port(self.sock)
- self.flag = None
- self.active = False
- self.selected_npn_protocols = []
- self.selected_alpn_protocols = []
- self.shared_ciphers = []
- self.conn_errors = []
- threading.Thread.__init__(self)
- self.daemon = True
-
- def __enter__(self):
- self.start(threading.Event())
- self.flag.wait()
- return self
-
- def __exit__(self, *args):
- self.stop()
- self.join()
-
- def start(self, flag=None):
- self.flag = flag
- threading.Thread.start(self)
+ elif stripped == b'over':
+ if support.verbose and self.server.connectionchatty:
+ sys.stdout.write(" server: client closed connection\n")
+ self.close()
+ return
+ elif (self.server.starttls_server and
+ stripped == b'STARTTLS'):
+ if support.verbose and self.server.connectionchatty:
+ sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
+ self.write(b"OK\n")
+ if not self.wrap_conn():
+ return
+ elif (self.server.starttls_server and self.sslconn
+ and stripped == b'ENDTLS'):
+ if support.verbose and self.server.connectionchatty:
+ sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
+ self.write(b"OK\n")
+ self.sock = self.sslconn.unwrap()
+ self.sslconn = None
+ if support.verbose and self.server.connectionchatty:
+ sys.stdout.write(" server: connection is now unencrypted...\n")
+ elif stripped == b'CB tls-unique':
+ if support.verbose and self.server.connectionchatty:
+ sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
+ data = self.sslconn.get_channel_binding("tls-unique")
+ self.write(repr(data).encode("us-ascii") + b"\n")
+ else:
+ if (support.verbose and
+ self.server.connectionchatty):
+ ctype = (self.sslconn and "encrypted") or "unencrypted"
+ sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
+ % (msg, ctype, msg.lower(), ctype))
+ self.write(msg.lower())
+ except OSError:
+ if self.server.chatty:
+ handle_error("Test server failure:\n")
+ self.close()
+ self.running = False
+ # normally, we'd just stop here, but for the test
+ # harness, we want to stop the server
+ self.server.stop()
- def run(self):
- self.sock.settimeout(0.05)
- self.sock.listen()
- self.active = True
- if self.flag:
- # signal an event
- self.flag.set()
- while self.active:
- try:
- newconn, connaddr = self.sock.accept()
- if support.verbose and self.chatty:
- sys.stdout.write(' server: new connection from '
- + repr(connaddr) + '\n')
- handler = self.ConnectionHandler(self, newconn, connaddr)
- handler.start()
- handler.join()
- except socket.timeout:
- pass
- except KeyboardInterrupt:
- self.stop()
- self.sock.close()
+ def __init__(self, certificate=None, ssl_version=None,
+ certreqs=None, cacerts=None,
+ chatty=True, connectionchatty=False, starttls_server=False,
+ npn_protocols=None, alpn_protocols=None,
+ ciphers=None, context=None):
+ if context:
+ self.context = context
+ else:
+ self.context = ssl.SSLContext(ssl_version
+ if ssl_version is not None
+ else ssl.PROTOCOL_TLSv1)
+ self.context.verify_mode = (certreqs if certreqs is not None
+ else ssl.CERT_NONE)
+ if cacerts:
+ self.context.load_verify_locations(cacerts)
+ if certificate:
+ self.context.load_cert_chain(certificate)
+ if npn_protocols:
+ self.context.set_npn_protocols(npn_protocols)
+ if alpn_protocols:
+ self.context.set_alpn_protocols(alpn_protocols)
+ if ciphers:
+ self.context.set_ciphers(ciphers)
+ self.chatty = chatty
+ self.connectionchatty = connectionchatty
+ self.starttls_server = starttls_server
+ self.sock = socket.socket()
+ self.port = support.bind_port(self.sock)
+ self.flag = None
+ self.active = False
+ self.selected_npn_protocols = []
+ self.selected_alpn_protocols = []
+ self.shared_ciphers = []
+ self.conn_errors = []
+ threading.Thread.__init__(self)
+ self.daemon = True
+
+ def __enter__(self):
+ self.start(threading.Event())
+ self.flag.wait()
+ return self
+
+ def __exit__(self, *args):
+ self.stop()
+ self.join()
+
+ def start(self, flag=None):
+ self.flag = flag
+ threading.Thread.start(self)
+
+ def run(self):
+ self.sock.settimeout(0.05)
+ self.sock.listen()
+ self.active = True
+ if self.flag:
+ # signal an event
+ self.flag.set()
+ while self.active:
+ try:
+ newconn, connaddr = self.sock.accept()
+ if support.verbose and self.chatty:
+ sys.stdout.write(' server: new connection from '
+ + repr(connaddr) + '\n')
+ handler = self.ConnectionHandler(self, newconn, connaddr)
+ handler.start()
+ handler.join()
+ except socket.timeout:
+ pass
+ except KeyboardInterrupt:
+ self.stop()
+ self.sock.close()
- def stop(self):
- self.active = False
+ def stop(self):
+ self.active = False
- class AsyncoreEchoServer(threading.Thread):
+class AsyncoreEchoServer(threading.Thread):
- # this one's based on asyncore.dispatcher
+ # this one's based on asyncore.dispatcher
- class EchoServer (asyncore.dispatcher):
+ class EchoServer (asyncore.dispatcher):
- class ConnectionHandler(asyncore.dispatcher_with_send):
+ class ConnectionHandler(asyncore.dispatcher_with_send):
- def __init__(self, conn, certfile):
- self.socket = test_wrap_socket(conn, server_side=True,
- certfile=certfile,
- do_handshake_on_connect=False)
- asyncore.dispatcher_with_send.__init__(self, self.socket)
- self._ssl_accepting = True
- self._do_ssl_handshake()
+ def __init__(self, conn, certfile):
+ self.socket = test_wrap_socket(conn, server_side=True,
+ certfile=certfile,
+ do_handshake_on_connect=False)
+ asyncore.dispatcher_with_send.__init__(self, self.socket)
+ self._ssl_accepting = True
+ self._do_ssl_handshake()
- def readable(self):
- if isinstance(self.socket, ssl.SSLSocket):
- while self.socket.pending() > 0:
- self.handle_read_event()
- return True
+ def readable(self):
+ if isinstance(self.socket, ssl.SSLSocket):
+ while self.socket.pending() > 0:
+ self.handle_read_event()
+ return True
- def _do_ssl_handshake(self):
- try:
- self.socket.do_handshake()
- except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
- return
- except ssl.SSLEOFError:
+ def _do_ssl_handshake(self):
+ try:
+ self.socket.do_handshake()
+ except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
+ return
+ except ssl.SSLEOFError:
+ return self.handle_close()
+ except ssl.SSLError:
+ raise
+ except OSError as err:
+ if err.args[0] == errno.ECONNABORTED:
return self.handle_close()
- except ssl.SSLError:
- raise
- except OSError as err:
- if err.args[0] == errno.ECONNABORTED:
- return self.handle_close()
- else:
- self._ssl_accepting = False
-
- def handle_read(self):
- if self._ssl_accepting:
- self._do_ssl_handshake()
- else:
- data = self.recv(1024)
- if support.verbose:
- sys.stdout.write(" server: read %s from client\n" % repr(data))
- if not data:
- self.close()
- else:
- self.send(data.lower())
+ else:
+ self._ssl_accepting = False
- def handle_close(self):
- self.close()
+ def handle_read(self):
+ if self._ssl_accepting:
+ self._do_ssl_handshake()
+ else:
+ data = self.recv(1024)
if support.verbose:
- sys.stdout.write(" server: closed connection %s\n" % self.socket)
-
- def handle_error(self):
- raise
-
- def __init__(self, certfile):
- self.certfile = certfile
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.port = support.bind_port(sock, '')
- asyncore.dispatcher.__init__(self, sock)
- self.listen(5)
+ sys.stdout.write(" server: read %s from client\n" % repr(data))
+ if not data:
+ self.close()
+ else:
+ self.send(data.lower())
- def handle_accepted(self, sock_obj, addr):
+ def handle_close(self):
+ self.close()
if support.verbose:
- sys.stdout.write(" server: new connection from %s:%s\n" %addr)
- self.ConnectionHandler(sock_obj, self.certfile)
+ sys.stdout.write(" server: closed connection %s\n" % self.socket)
def handle_error(self):
raise
def __init__(self, certfile):
- self.flag = None
- self.active = False
- self.server = self.EchoServer(certfile)
- self.port = self.server.port
- threading.Thread.__init__(self)
- self.daemon = True
+ self.certfile = certfile
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.port = support.bind_port(sock, '')
+ asyncore.dispatcher.__init__(self, sock)
+ self.listen(5)
- def __str__(self):
- return "<%s %s>" % (self.__class__.__name__, self.server)
+ def handle_accepted(self, sock_obj, addr):
+ if support.verbose:
+ sys.stdout.write(" server: new connection from %s:%s\n" %addr)
+ self.ConnectionHandler(sock_obj, self.certfile)
- def __enter__(self):
- self.start(threading.Event())
- self.flag.wait()
- return self
+ def handle_error(self):
+ raise
- def __exit__(self, *args):
- if support.verbose:
- sys.stdout.write(" cleanup: stopping server.\n")
- self.stop()
- if support.verbose:
- sys.stdout.write(" cleanup: joining server thread.\n")
- self.join()
- if support.verbose:
- sys.stdout.write(" cleanup: successfully joined.\n")
- # make sure that ConnectionHandler is removed from socket_map
- asyncore.close_all(ignore_all=True)
+ def __init__(self, certfile):
+ self.flag = None
+ self.active = False
+ self.server = self.EchoServer(certfile)
+ self.port = self.server.port
+ threading.Thread.__init__(self)
+ self.daemon = True
- def start (self, flag=None):
- self.flag = flag
- threading.Thread.start(self)
+ def __str__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.server)
- def run(self):
- self.active = True
- if self.flag:
- self.flag.set()
- while self.active:
- try:
- asyncore.loop(1)
- except:
- pass
+ def __enter__(self):
+ self.start(threading.Event())
+ self.flag.wait()
+ return self
- def stop(self):
- self.active = False
- self.server.close()
+ def __exit__(self, *args):
+ if support.verbose:
+ sys.stdout.write(" cleanup: stopping server.\n")
+ self.stop()
+ if support.verbose:
+ sys.stdout.write(" cleanup: joining server thread.\n")
+ self.join()
+ if support.verbose:
+ sys.stdout.write(" cleanup: successfully joined.\n")
+ # make sure that ConnectionHandler is removed from socket_map
+ asyncore.close_all(ignore_all=True)
+
+ def start (self, flag=None):
+ self.flag = flag
+ threading.Thread.start(self)
+
+ def run(self):
+ self.active = True
+ if self.flag:
+ self.flag.set()
+ while self.active:
+ try:
+ asyncore.loop(1)
+ except:
+ pass
- def server_params_test(client_context, server_context, indata=b"FOO\n",
- chatty=True, connectionchatty=False, sni_name=None,
- session=None):
- """
- Launch a server, connect a client to it and try various reads
- and writes.
- """
- stats = {}
- server = ThreadedEchoServer(context=server_context,
- chatty=chatty,
- connectionchatty=False)
- with server:
- with client_context.wrap_socket(socket.socket(),
- server_hostname=sni_name, session=session) as s:
- s.connect((HOST, server.port))
- for arg in [indata, bytearray(indata), memoryview(indata)]:
- if connectionchatty:
- if support.verbose:
- sys.stdout.write(
- " client: sending %r...\n" % indata)
- s.write(arg)
- outdata = s.read()
- if connectionchatty:
- if support.verbose:
- sys.stdout.write(" client: read %r\n" % outdata)
- if outdata != indata.lower():
- raise AssertionError(
- "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
- % (outdata[:20], len(outdata),
- indata[:20].lower(), len(indata)))
- s.write(b"over\n")
+ def stop(self):
+ self.active = False
+ self.server.close()
+
+def server_params_test(client_context, server_context, indata=b"FOO\n",
+ chatty=True, connectionchatty=False, sni_name=None,
+ session=None):
+ """
+ Launch a server, connect a client to it and try various reads
+ and writes.
+ """
+ stats = {}
+ server = ThreadedEchoServer(context=server_context,
+ chatty=chatty,
+ connectionchatty=False)
+ with server:
+ with client_context.wrap_socket(socket.socket(),
+ server_hostname=sni_name, session=session) as s:
+ s.connect((HOST, server.port))
+ for arg in [indata, bytearray(indata), memoryview(indata)]:
if connectionchatty:
if support.verbose:
- sys.stdout.write(" client: closing connection.\n")
- stats.update({
- 'compression': s.compression(),
- 'cipher': s.cipher(),
- 'peercert': s.getpeercert(),
- 'client_alpn_protocol': s.selected_alpn_protocol(),
- 'client_npn_protocol': s.selected_npn_protocol(),
- 'version': s.version(),
- 'session_reused': s.session_reused,
- 'session': s.session,
- })
- s.close()
- stats['server_alpn_protocols'] = server.selected_alpn_protocols
- stats['server_npn_protocols'] = server.selected_npn_protocols
- stats['server_shared_ciphers'] = server.shared_ciphers
- return stats
+ sys.stdout.write(
+ " client: sending %r...\n" % indata)
+ s.write(arg)
+ outdata = s.read()
+ if connectionchatty:
+ if support.verbose:
+ sys.stdout.write(" client: read %r\n" % outdata)
+ if outdata != indata.lower():
+ raise AssertionError(
+ "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
+ % (outdata[:20], len(outdata),
+ indata[:20].lower(), len(indata)))
+ s.write(b"over\n")
+ if connectionchatty:
+ if support.verbose:
+ sys.stdout.write(" client: closing connection.\n")
+ stats.update({
+ 'compression': s.compression(),
+ 'cipher': s.cipher(),
+ 'peercert': s.getpeercert(),
+ 'client_alpn_protocol': s.selected_alpn_protocol(),
+ 'client_npn_protocol': s.selected_npn_protocol(),
+ 'version': s.version(),
+ 'session_reused': s.session_reused,
+ 'session': s.session,
+ })
+ s.close()
+ stats['server_alpn_protocols'] = server.selected_alpn_protocols
+ stats['server_npn_protocols'] = server.selected_npn_protocols
+ stats['server_shared_ciphers'] = server.shared_ciphers
+ return stats
+
+def try_protocol_combo(server_protocol, client_protocol, expect_success,
+ certsreqs=None, server_options=0, client_options=0):
+ """
+ Try to SSL-connect using *client_protocol* to *server_protocol*.
+ If *expect_success* is true, assert that the connection succeeds,
+ if it's false, assert that the connection fails.
+ Also, if *expect_success* is a string, assert that it is the protocol
+ version actually used by the connection.
+ """
+ if certsreqs is None:
+ certsreqs = ssl.CERT_NONE
+ certtype = {
+ ssl.CERT_NONE: "CERT_NONE",
+ ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
+ ssl.CERT_REQUIRED: "CERT_REQUIRED",
+ }[certsreqs]
+ if support.verbose:
+ formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
+ sys.stdout.write(formatstr %
+ (ssl.get_protocol_name(client_protocol),
+ ssl.get_protocol_name(server_protocol),
+ certtype))
+ client_context = ssl.SSLContext(client_protocol)
+ client_context.options |= client_options
+ server_context = ssl.SSLContext(server_protocol)
+ server_context.options |= server_options
+
+ # NOTE: we must enable "ALL" ciphers on the client, otherwise an
+ # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
+ # starting from OpenSSL 1.0.0 (see issue #8322).
+ if client_context.protocol == ssl.PROTOCOL_SSLv23:
+ client_context.set_ciphers("ALL")
+
+ for ctx in (client_context, server_context):
+ ctx.verify_mode = certsreqs
+ ctx.load_cert_chain(CERTFILE)
+ ctx.load_verify_locations(CERTFILE)
+ try:
+ stats = server_params_test(client_context, server_context,
+ chatty=False, connectionchatty=False)
+ # Protocol mismatch can result in either an SSLError, or a
+ # "Connection reset by peer" error.
+ except ssl.SSLError:
+ if expect_success:
+ raise
+ except OSError as e:
+ if expect_success or e.errno != errno.ECONNRESET:
+ raise
+ else:
+ if not expect_success:
+ raise AssertionError(
+ "Client protocol %s succeeded with server protocol %s!"
+ % (ssl.get_protocol_name(client_protocol),
+ ssl.get_protocol_name(server_protocol)))
+ elif (expect_success is not True
+ and expect_success != stats['version']):
+ raise AssertionError("version mismatch: expected %r, got %r"
+ % (expect_success, stats['version']))
- def try_protocol_combo(server_protocol, client_protocol, expect_success,
- certsreqs=None, server_options=0, client_options=0):
- """
- Try to SSL-connect using *client_protocol* to *server_protocol*.
- If *expect_success* is true, assert that the connection succeeds,
- if it's false, assert that the connection fails.
- Also, if *expect_success* is a string, assert that it is the protocol
- version actually used by the connection.
- """
- if certsreqs is None:
- certsreqs = ssl.CERT_NONE
- certtype = {
- ssl.CERT_NONE: "CERT_NONE",
- ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
- ssl.CERT_REQUIRED: "CERT_REQUIRED",
- }[certsreqs]
- if support.verbose:
- formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
- sys.stdout.write(formatstr %
- (ssl.get_protocol_name(client_protocol),
- ssl.get_protocol_name(server_protocol),
- certtype))
- client_context = ssl.SSLContext(client_protocol)
- client_context.options |= client_options
- server_context = ssl.SSLContext(server_protocol)
- server_context.options |= server_options
-
- # NOTE: we must enable "ALL" ciphers on the client, otherwise an
- # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
- # starting from OpenSSL 1.0.0 (see issue #8322).
- if client_context.protocol == ssl.PROTOCOL_SSLv23:
- client_context.set_ciphers("ALL")
-
- for ctx in (client_context, server_context):
- ctx.verify_mode = certsreqs
- ctx.load_cert_chain(CERTFILE)
- ctx.load_verify_locations(CERTFILE)
- try:
- stats = server_params_test(client_context, server_context,
- chatty=False, connectionchatty=False)
- # Protocol mismatch can result in either an SSLError, or a
- # "Connection reset by peer" error.
- except ssl.SSLError:
- if expect_success:
- raise
- except OSError as e:
- if expect_success or e.errno != errno.ECONNRESET:
- raise
- else:
- if not expect_success:
- raise AssertionError(
- "Client protocol %s succeeded with server protocol %s!"
- % (ssl.get_protocol_name(client_protocol),
- ssl.get_protocol_name(server_protocol)))
- elif (expect_success is not True
- and expect_success != stats['version']):
- raise AssertionError("version mismatch: expected %r, got %r"
- % (expect_success, stats['version']))
-
-
- class ThreadedTests(unittest.TestCase):
-
- @skip_if_broken_ubuntu_ssl
- def test_echo(self):
- """Basic test of an SSL client connecting to a server"""
- if support.verbose:
- sys.stdout.write("\n")
- for protocol in PROTOCOLS:
- if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
- continue
- with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
- context = ssl.SSLContext(protocol)
- context.load_cert_chain(CERTFILE)
- server_params_test(context, context,
- chatty=True, connectionchatty=True)
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
- client_context.load_verify_locations(SIGNING_CA)
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
- # server_context.load_verify_locations(SIGNING_CA)
- server_context.load_cert_chain(SIGNED_CERTFILE2)
+class ThreadedTests(unittest.TestCase):
- with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_SERVER):
- server_params_test(client_context=client_context,
- server_context=server_context,
+ @skip_if_broken_ubuntu_ssl
+ def test_echo(self):
+ """Basic test of an SSL client connecting to a server"""
+ if support.verbose:
+ sys.stdout.write("\n")
+ for protocol in PROTOCOLS:
+ if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
+ continue
+ with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
+ context = ssl.SSLContext(protocol)
+ context.load_cert_chain(CERTFILE)
+ server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ client_context.load_verify_locations(SIGNING_CA)
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ # server_context.load_verify_locations(SIGNING_CA)
+ server_context.load_cert_chain(SIGNED_CERTFILE2)
+
+ with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_SERVER):
+ server_params_test(client_context=client_context,
+ server_context=server_context,
+ chatty=True, connectionchatty=True,
+ sni_name='fakehostname')
+
+ client_context.check_hostname = False
+ with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT):
+ with self.assertRaises(ssl.SSLError) as e:
+ server_params_test(client_context=server_context,
+ server_context=client_context,
chatty=True, connectionchatty=True,
sni_name='fakehostname')
+ self.assertIn('called a function you should not call',
+ str(e.exception))
- client_context.check_hostname = False
- with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT):
- with self.assertRaises(ssl.SSLError) as e:
- server_params_test(client_context=server_context,
- server_context=client_context,
- chatty=True, connectionchatty=True,
- sni_name='fakehostname')
- self.assertIn('called a function you should not call',
- str(e.exception))
-
- with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER):
- with self.assertRaises(ssl.SSLError) as e:
- server_params_test(client_context=server_context,
- server_context=server_context,
- chatty=True, connectionchatty=True)
- self.assertIn('called a function you should not call',
- str(e.exception))
+ with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER):
+ with self.assertRaises(ssl.SSLError) as e:
+ server_params_test(client_context=server_context,
+ server_context=server_context,
+ chatty=True, connectionchatty=True)
+ self.assertIn('called a function you should not call',
+ str(e.exception))
- with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_CLIENT):
- with self.assertRaises(ssl.SSLError) as e:
- server_params_test(client_context=server_context,
- server_context=client_context,
- chatty=True, connectionchatty=True)
- self.assertIn('called a function you should not call',
- str(e.exception))
+ with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_CLIENT):
+ with self.assertRaises(ssl.SSLError) as e:
+ server_params_test(client_context=server_context,
+ server_context=client_context,
+ chatty=True, connectionchatty=True)
+ self.assertIn('called a function you should not call',
+ str(e.exception))
- def test_getpeercert(self):
+ def test_getpeercert(self):
+ if support.verbose:
+ sys.stdout.write("\n")
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(CERTFILE)
+ context.load_cert_chain(CERTFILE)
+ server = ThreadedEchoServer(context=context, chatty=False)
+ with server:
+ s = context.wrap_socket(socket.socket(),
+ do_handshake_on_connect=False)
+ s.connect((HOST, server.port))
+ # getpeercert() raise ValueError while the handshake isn't
+ # done.
+ with self.assertRaises(ValueError):
+ s.getpeercert()
+ s.do_handshake()
+ cert = s.getpeercert()
+ self.assertTrue(cert, "Can't get peer certificate.")
+ cipher = s.cipher()
if support.verbose:
- sys.stdout.write("\n")
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(CERTFILE)
- context.load_cert_chain(CERTFILE)
- server = ThreadedEchoServer(context=context, chatty=False)
- with server:
- s = context.wrap_socket(socket.socket(),
- do_handshake_on_connect=False)
+ sys.stdout.write(pprint.pformat(cert) + '\n')
+ sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
+ if 'subject' not in cert:
+ self.fail("No subject field in certificate: %s." %
+ pprint.pformat(cert))
+ if ((('organizationName', 'Python Software Foundation'),)
+ not in cert['subject']):
+ self.fail(
+ "Missing or invalid 'organizationName' field in certificate subject; "
+ "should be 'Python Software Foundation'.")
+ self.assertIn('notBefore', cert)
+ self.assertIn('notAfter', cert)
+ before = ssl.cert_time_to_seconds(cert['notBefore'])
+ after = ssl.cert_time_to_seconds(cert['notAfter'])
+ self.assertLess(before, after)
+ s.close()
+
+ @unittest.skipUnless(have_verify_flags(),
+ "verify_flags need OpenSSL > 0.9.8")
+ def test_crl_check(self):
+ if support.verbose:
+ sys.stdout.write("\n")
+
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(SIGNING_CA)
+ tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
+ self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
+
+ # VERIFY_DEFAULT should pass
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
- # getpeercert() raise ValueError while the handshake isn't
- # done.
- with self.assertRaises(ValueError):
- s.getpeercert()
- s.do_handshake()
cert = s.getpeercert()
self.assertTrue(cert, "Can't get peer certificate.")
- cipher = s.cipher()
- if support.verbose:
- sys.stdout.write(pprint.pformat(cert) + '\n')
- sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
- if 'subject' not in cert:
- self.fail("No subject field in certificate: %s." %
- pprint.pformat(cert))
- if ((('organizationName', 'Python Software Foundation'),)
- not in cert['subject']):
- self.fail(
- "Missing or invalid 'organizationName' field in certificate subject; "
- "should be 'Python Software Foundation'.")
- self.assertIn('notBefore', cert)
- self.assertIn('notAfter', cert)
- before = ssl.cert_time_to_seconds(cert['notBefore'])
- after = ssl.cert_time_to_seconds(cert['notAfter'])
- self.assertLess(before, after)
- s.close()
- @unittest.skipUnless(have_verify_flags(),
- "verify_flags need OpenSSL > 0.9.8")
- def test_crl_check(self):
- if support.verbose:
- sys.stdout.write("\n")
+ # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
+ context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(SIGNED_CERTFILE)
-
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(SIGNING_CA)
- tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
- self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
-
- # VERIFY_DEFAULT should pass
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with context.wrap_socket(socket.socket()) as s:
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with context.wrap_socket(socket.socket()) as s:
+ with self.assertRaisesRegex(ssl.SSLError,
+ "certificate verify failed"):
s.connect((HOST, server.port))
- cert = s.getpeercert()
- self.assertTrue(cert, "Can't get peer certificate.")
- # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
- context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
+ # now load a CRL file. The CRL file is signed by the CA.
+ context.load_verify_locations(CRLFILE)
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with context.wrap_socket(socket.socket()) as s:
- with self.assertRaisesRegex(ssl.SSLError,
- "certificate verify failed"):
- s.connect((HOST, server.port))
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with context.wrap_socket(socket.socket()) as s:
+ s.connect((HOST, server.port))
+ cert = s.getpeercert()
+ self.assertTrue(cert, "Can't get peer certificate.")
- # now load a CRL file. The CRL file is signed by the CA.
- context.load_verify_locations(CRLFILE)
+ def test_check_hostname(self):
+ if support.verbose:
+ sys.stdout.write("\n")
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with context.wrap_socket(socket.socket()) as s:
- s.connect((HOST, server.port))
- cert = s.getpeercert()
- self.assertTrue(cert, "Can't get peer certificate.")
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
- def test_check_hostname(self):
- if support.verbose:
- sys.stdout.write("\n")
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.check_hostname = True
+ context.load_verify_locations(SIGNING_CA)
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(SIGNED_CERTFILE)
-
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.verify_mode = ssl.CERT_REQUIRED
- context.check_hostname = True
- context.load_verify_locations(SIGNING_CA)
-
- # correct hostname should verify
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with context.wrap_socket(socket.socket(),
- server_hostname="localhost") as s:
+ # correct hostname should verify
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with context.wrap_socket(socket.socket(),
+ server_hostname="localhost") as s:
+ s.connect((HOST, server.port))
+ cert = s.getpeercert()
+ self.assertTrue(cert, "Can't get peer certificate.")
+
+ # incorrect hostname should raise an exception
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with context.wrap_socket(socket.socket(),
+ server_hostname="invalid") as s:
+ with self.assertRaisesRegex(ssl.CertificateError,
+ "hostname 'invalid' doesn't match 'localhost'"):
s.connect((HOST, server.port))
- cert = s.getpeercert()
- self.assertTrue(cert, "Can't get peer certificate.")
-
- # incorrect hostname should raise an exception
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with context.wrap_socket(socket.socket(),
- server_hostname="invalid") as s:
- with self.assertRaisesRegex(ssl.CertificateError,
- "hostname 'invalid' doesn't match 'localhost'"):
- s.connect((HOST, server.port))
-
- # missing server_hostname arg should cause an exception, too
- server = ThreadedEchoServer(context=server_context, chatty=True)
- with server:
- with socket.socket() as s:
- with self.assertRaisesRegex(ValueError,
- "check_hostname requires server_hostname"):
- context.wrap_socket(s)
-
- def test_wrong_cert(self):
- """Connecting when the server rejects the client's certificate
-
- Launch a server with CERT_REQUIRED, and check that trying to
- connect to it with a wrong client certificate fails.
- """
- certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
- "wrongcert.pem")
- server = ThreadedEchoServer(CERTFILE,
- certreqs=ssl.CERT_REQUIRED,
- cacerts=CERTFILE, chatty=False,
- connectionchatty=False)
- with server, \
- socket.socket() as sock, \
- test_wrap_socket(sock,
- certfile=certfile,
- ssl_version=ssl.PROTOCOL_TLSv1) as s:
+
+ # missing server_hostname arg should cause an exception, too
+ server = ThreadedEchoServer(context=server_context, chatty=True)
+ with server:
+ with socket.socket() as s:
+ with self.assertRaisesRegex(ValueError,
+ "check_hostname requires server_hostname"):
+ context.wrap_socket(s)
+
+ def test_wrong_cert(self):
+ """Connecting when the server rejects the client's certificate
+
+ Launch a server with CERT_REQUIRED, and check that trying to
+ connect to it with a wrong client certificate fails.
+ """
+ certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
+ "wrongcert.pem")
+ server = ThreadedEchoServer(CERTFILE,
+ certreqs=ssl.CERT_REQUIRED,
+ cacerts=CERTFILE, chatty=False,
+ connectionchatty=False)
+ with server, \
+ socket.socket() as sock, \
+ test_wrap_socket(sock,
+ certfile=certfile,
+ ssl_version=ssl.PROTOCOL_TLSv1) as s:
+ try:
+ # Expect either an SSL error about the server rejecting
+ # the connection, or a low-level connection reset (which
+ # sometimes happens on Windows)
+ s.connect((HOST, server.port))
+ except ssl.SSLError as e:
+ if support.verbose:
+ sys.stdout.write("\nSSLError is %r\n" % e)
+ except OSError as e:
+ if e.errno != errno.ECONNRESET:
+ raise
+ if support.verbose:
+ sys.stdout.write("\nsocket.error is %r\n" % e)
+ else:
+ self.fail("Use of invalid cert should have failed!")
+
+ def test_rude_shutdown(self):
+ """A brutal shutdown of an SSL server should raise an OSError
+ in the client when attempting handshake.
+ """
+ listener_ready = threading.Event()
+ listener_gone = threading.Event()
+
+ s = socket.socket()
+ port = support.bind_port(s, HOST)
+
+ # `listener` runs in a thread. It sits in an accept() until
+ # the main thread connects. Then it rudely closes the socket,
+ # and sets Event `listener_gone` to let the main thread know
+ # the socket is gone.
+ def listener():
+ s.listen()
+ listener_ready.set()
+ newsock, addr = s.accept()
+ newsock.close()
+ s.close()
+ listener_gone.set()
+
+ def connector():
+ listener_ready.wait()
+ with socket.socket() as c:
+ c.connect((HOST, port))
+ listener_gone.wait()
try:
- # Expect either an SSL error about the server rejecting
- # the connection, or a low-level connection reset (which
- # sometimes happens on Windows)
- s.connect((HOST, server.port))
- except ssl.SSLError as e:
- if support.verbose:
- sys.stdout.write("\nSSLError is %r\n" % e)
- except OSError as e:
- if e.errno != errno.ECONNRESET:
- raise
- if support.verbose:
- sys.stdout.write("\nsocket.error is %r\n" % e)
+ ssl_sock = test_wrap_socket(c)
+ except OSError:
+ pass
else:
- self.fail("Use of invalid cert should have failed!")
+ self.fail('connecting to closed SSL socket should have failed')
- def test_rude_shutdown(self):
- """A brutal shutdown of an SSL server should raise an OSError
- in the client when attempting handshake.
- """
- listener_ready = threading.Event()
- listener_gone = threading.Event()
+ t = threading.Thread(target=listener)
+ t.start()
+ try:
+ connector()
+ finally:
+ t.join()
- s = socket.socket()
- port = support.bind_port(s, HOST)
-
- # `listener` runs in a thread. It sits in an accept() until
- # the main thread connects. Then it rudely closes the socket,
- # and sets Event `listener_gone` to let the main thread know
- # the socket is gone.
- def listener():
- s.listen()
- listener_ready.set()
- newsock, addr = s.accept()
- newsock.close()
- s.close()
- listener_gone.set()
-
- def connector():
- listener_ready.wait()
- with socket.socket() as c:
- c.connect((HOST, port))
- listener_gone.wait()
- try:
- ssl_sock = test_wrap_socket(c)
- except OSError:
- pass
- else:
- self.fail('connecting to closed SSL socket should have failed')
+ @skip_if_broken_ubuntu_ssl
+ @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
+ "OpenSSL is compiled without SSLv2 support")
+ def test_protocol_sslv2(self):
+ """Connecting to an SSLv2 server with various client options"""
+ if support.verbose:
+ sys.stdout.write("\n")
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
+ # SSLv23 client with specific SSL options
+ if no_sslv2_implies_sslv3_hello():
+ # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_SSLv2)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_SSLv3)
+ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_TLSv1)
- t = threading.Thread(target=listener)
- t.start()
+ @skip_if_broken_ubuntu_ssl
+ def test_protocol_sslv23(self):
+ """Connecting to an SSLv23 server with various client options"""
+ if support.verbose:
+ sys.stdout.write("\n")
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
try:
- connector()
- finally:
- t.join()
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
+ except OSError as x:
+ # this fails on some older versions of OpenSSL (0.9.7l, for instance)
+ if support.verbose:
+ sys.stdout.write(
+ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
+ % str(x))
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
+
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
+
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
+
+ # Server with specific SSL options
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
+ server_options=ssl.OP_NO_SSLv3)
+ # Will choose TLSv1
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
+ server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
+ server_options=ssl.OP_NO_TLSv1)
+
+
+ @skip_if_broken_ubuntu_ssl
+ @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
+ "OpenSSL is compiled without SSLv3 support")
+ def test_protocol_sslv3(self):
+ """Connecting to an SSLv3 server with various client options"""
+ if support.verbose:
+ sys.stdout.write("\n")
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_SSLv3)
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
+ if no_sslv2_implies_sslv3_hello():
+ # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
+ False, client_options=ssl.OP_NO_SSLv2)
+
+ @skip_if_broken_ubuntu_ssl
+ def test_protocol_tlsv1(self):
+ """Connecting to a TLSv1 server with various client options"""
+ if support.verbose:
+ sys.stdout.write("\n")
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_TLSv1)
+
+ @skip_if_broken_ubuntu_ssl
+ @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
+ "TLS version 1.1 not supported.")
+ def test_protocol_tlsv1_1(self):
+ """Connecting to a TLSv1.1 server with various client options.
+ Testing against older TLS versions."""
+ if support.verbose:
+ sys.stdout.write("\n")
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_TLSv1_1)
+
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
- @skip_if_broken_ubuntu_ssl
- @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
- "OpenSSL is compiled without SSLv2 support")
- def test_protocol_sslv2(self):
- """Connecting to an SSLv2 server with various client options"""
- if support.verbose:
- sys.stdout.write("\n")
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
- # SSLv23 client with specific SSL options
- if no_sslv2_implies_sslv3_hello():
- # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_SSLv2)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_SSLv3)
- try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_TLSv1)
- @skip_if_broken_ubuntu_ssl
- def test_protocol_sslv23(self):
- """Connecting to an SSLv23 server with various client options"""
+ @skip_if_broken_ubuntu_ssl
+ @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
+ "TLS version 1.2 not supported.")
+ def test_protocol_tlsv1_2(self):
+ """Connecting to a TLSv1.2 server with various client options.
+ Testing against older TLS versions."""
+ if support.verbose:
+ sys.stdout.write("\n")
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
+ server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
+ client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_TLSv1_2)
+
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
+
+ def test_starttls(self):
+ """Switching from clear text to encrypted and back again."""
+ msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
+
+ server = ThreadedEchoServer(CERTFILE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ starttls_server=True,
+ chatty=True,
+ connectionchatty=True)
+ wrapped = False
+ with server:
+ s = socket.socket()
+ s.setblocking(1)
+ s.connect((HOST, server.port))
if support.verbose:
sys.stdout.write("\n")
- if hasattr(ssl, 'PROTOCOL_SSLv2'):
- try:
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
- except OSError as x:
- # this fails on some older versions of OpenSSL (0.9.7l, for instance)
+ for indata in msgs:
+ if support.verbose:
+ sys.stdout.write(
+ " client: sending %r...\n" % indata)
+ if wrapped:
+ conn.write(indata)
+ outdata = conn.read()
+ else:
+ s.send(indata)
+ outdata = s.recv(1024)
+ msg = outdata.strip().lower()
+ if indata == b"STARTTLS" and msg.startswith(b"ok"):
+ # STARTTLS ok, switch to secure mode
if support.verbose:
sys.stdout.write(
- " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
- % str(x))
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
-
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
-
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
-
- # Server with specific SSL options
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
- server_options=ssl.OP_NO_SSLv3)
- # Will choose TLSv1
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
- server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
- server_options=ssl.OP_NO_TLSv1)
-
-
- @skip_if_broken_ubuntu_ssl
- @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
- "OpenSSL is compiled without SSLv3 support")
- def test_protocol_sslv3(self):
- """Connecting to an SSLv3 server with various client options"""
- if support.verbose:
- sys.stdout.write("\n")
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
- if hasattr(ssl, 'PROTOCOL_SSLv2'):
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_SSLv3)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
- if no_sslv2_implies_sslv3_hello():
- # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
- False, client_options=ssl.OP_NO_SSLv2)
-
- @skip_if_broken_ubuntu_ssl
- def test_protocol_tlsv1(self):
- """Connecting to a TLSv1 server with various client options"""
- if support.verbose:
- sys.stdout.write("\n")
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
- if hasattr(ssl, 'PROTOCOL_SSLv2'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_TLSv1)
-
- @skip_if_broken_ubuntu_ssl
- @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
- "TLS version 1.1 not supported.")
- def test_protocol_tlsv1_1(self):
- """Connecting to a TLSv1.1 server with various client options.
- Testing against older TLS versions."""
- if support.verbose:
- sys.stdout.write("\n")
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
- if hasattr(ssl, 'PROTOCOL_SSLv2'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_TLSv1_1)
-
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
-
-
- @skip_if_broken_ubuntu_ssl
- @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
- "TLS version 1.2 not supported.")
- def test_protocol_tlsv1_2(self):
- """Connecting to a TLSv1.2 server with various client options.
- Testing against older TLS versions."""
- if support.verbose:
- sys.stdout.write("\n")
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
- server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
- client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
- if hasattr(ssl, 'PROTOCOL_SSLv2'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
- if hasattr(ssl, 'PROTOCOL_SSLv3'):
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
- client_options=ssl.OP_NO_TLSv1_2)
-
- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
- try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
-
- def test_starttls(self):
- """Switching from clear text to encrypted and back again."""
- msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
-
- server = ThreadedEchoServer(CERTFILE,
- ssl_version=ssl.PROTOCOL_TLSv1,
- starttls_server=True,
- chatty=True,
- connectionchatty=True)
- wrapped = False
- with server:
- s = socket.socket()
- s.setblocking(1)
- s.connect((HOST, server.port))
- if support.verbose:
- sys.stdout.write("\n")
- for indata in msgs:
+ " client: read %r from server, starting TLS...\n"
+ % msg)
+ conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
+ wrapped = True
+ elif indata == b"ENDTLS" and msg.startswith(b"ok"):
+ # ENDTLS ok, switch back to clear text
if support.verbose:
sys.stdout.write(
- " client: sending %r...\n" % indata)
- if wrapped:
- conn.write(indata)
- outdata = conn.read()
- else:
- s.send(indata)
- outdata = s.recv(1024)
- msg = outdata.strip().lower()
- if indata == b"STARTTLS" and msg.startswith(b"ok"):
- # STARTTLS ok, switch to secure mode
- if support.verbose:
- sys.stdout.write(
- " client: read %r from server, starting TLS...\n"
- % msg)
- conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
- wrapped = True
- elif indata == b"ENDTLS" and msg.startswith(b"ok"):
- # ENDTLS ok, switch back to clear text
- if support.verbose:
- sys.stdout.write(
- " client: read %r from server, ending TLS...\n"
- % msg)
- s = conn.unwrap()
- wrapped = False
- else:
- if support.verbose:
- sys.stdout.write(
- " client: read %r from server\n" % msg)
- if support.verbose:
- sys.stdout.write(" client: closing connection.\n")
- if wrapped:
- conn.write(b"over\n")
+ " client: read %r from server, ending TLS...\n"
+ % msg)
+ s = conn.unwrap()
+ wrapped = False
else:
- s.send(b"over\n")
- if wrapped:
- conn.close()
- else:
- s.close()
-
- def test_socketserver(self):
- """Using socketserver to create and manage SSL connections."""
- server = make_https_server(self, certfile=CERTFILE)
- # try to connect
- if support.verbose:
- sys.stdout.write('\n')
- with open(CERTFILE, 'rb') as f:
- d1 = f.read()
- d2 = ''
- # now fetch the same data from the HTTPS server
- url = 'https://localhost:%d/%s' % (
- server.port, os.path.split(CERTFILE)[1])
- context = ssl.create_default_context(cafile=CERTFILE)
- f = urllib.request.urlopen(url, context=context)
- try:
- dlen = f.info().get("content-length")
- if dlen and (int(dlen) > 0):
- d2 = f.read(int(dlen))
if support.verbose:
sys.stdout.write(
- " client: read %d bytes from remote server '%s'\n"
- % (len(d2), server))
- finally:
- f.close()
- self.assertEqual(d1, d2)
-
- def test_asyncore_server(self):
- """Check the example asyncore integration."""
+ " client: read %r from server\n" % msg)
if support.verbose:
- sys.stdout.write("\n")
+ sys.stdout.write(" client: closing connection.\n")
+ if wrapped:
+ conn.write(b"over\n")
+ else:
+ s.send(b"over\n")
+ if wrapped:
+ conn.close()
+ else:
+ s.close()
- indata = b"FOO\n"
- server = AsyncoreEchoServer(CERTFILE)
- with server:
- s = test_wrap_socket(socket.socket())
- s.connect(('127.0.0.1', server.port))
+ def test_socketserver(self):
+ """Using socketserver to create and manage SSL connections."""
+ server = make_https_server(self, certfile=CERTFILE)
+ # try to connect
+ if support.verbose:
+ sys.stdout.write('\n')
+ with open(CERTFILE, 'rb') as f:
+ d1 = f.read()
+ d2 = ''
+ # now fetch the same data from the HTTPS server
+ url = 'https://localhost:%d/%s' % (
+ server.port, os.path.split(CERTFILE)[1])
+ context = ssl.create_default_context(cafile=CERTFILE)
+ f = urllib.request.urlopen(url, context=context)
+ try:
+ dlen = f.info().get("content-length")
+ if dlen and (int(dlen) > 0):
+ d2 = f.read(int(dlen))
if support.verbose:
sys.stdout.write(
- " client: sending %r...\n" % indata)
- s.write(indata)
- outdata = s.read()
- if support.verbose:
- sys.stdout.write(" client: read %r\n" % outdata)
- if outdata != indata.lower():
- self.fail(
- "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
- % (outdata[:20], len(outdata),
- indata[:20].lower(), len(indata)))
- s.write(b"over\n")
- if support.verbose:
- sys.stdout.write(" client: closing connection.\n")
- s.close()
- if support.verbose:
- sys.stdout.write(" client: connection closed.\n")
+ " client: read %d bytes from remote server '%s'\n"
+ % (len(d2), server))
+ finally:
+ f.close()
+ self.assertEqual(d1, d2)
- def test_recv_send(self):
- """Test recv(), send() and friends."""
+ def test_asyncore_server(self):
+ """Check the example asyncore integration."""
+ if support.verbose:
+ sys.stdout.write("\n")
+
+ indata = b"FOO\n"
+ server = AsyncoreEchoServer(CERTFILE)
+ with server:
+ s = test_wrap_socket(socket.socket())
+ s.connect(('127.0.0.1', server.port))
if support.verbose:
- sys.stdout.write("\n")
+ sys.stdout.write(
+ " client: sending %r...\n" % indata)
+ s.write(indata)
+ outdata = s.read()
+ if support.verbose:
+ sys.stdout.write(" client: read %r\n" % outdata)
+ if outdata != indata.lower():
+ self.fail(
+ "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
+ % (outdata[:20], len(outdata),
+ indata[:20].lower(), len(indata)))
+ s.write(b"over\n")
+ if support.verbose:
+ sys.stdout.write(" client: closing connection.\n")
+ s.close()
+ if support.verbose:
+ sys.stdout.write(" client: connection closed.\n")
- server = ThreadedEchoServer(CERTFILE,
- certreqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1,
- cacerts=CERTFILE,
- chatty=True,
- connectionchatty=False)
- with server:
- s = test_wrap_socket(socket.socket(),
- server_side=False,
- certfile=CERTFILE,
- ca_certs=CERTFILE,
- cert_reqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1)
- s.connect((HOST, server.port))
- # helper methods for standardising recv* method signatures
- def _recv_into():
- b = bytearray(b"\0"*100)
- count = s.recv_into(b)
- return b[:count]
-
- def _recvfrom_into():
- b = bytearray(b"\0"*100)
- count, addr = s.recvfrom_into(b)
- return b[:count]
-
- # (name, method, expect success?, *args, return value func)
- send_methods = [
- ('send', s.send, True, [], len),
- ('sendto', s.sendto, False, ["some.address"], len),
- ('sendall', s.sendall, True, [], lambda x: None),
- ]
- # (name, method, whether to expect success, *args)
- recv_methods = [
- ('recv', s.recv, True, []),
- ('recvfrom', s.recvfrom, False, ["some.address"]),
- ('recv_into', _recv_into, True, []),
- ('recvfrom_into', _recvfrom_into, False, []),
- ]
- data_prefix = "PREFIX_"
-
- for (meth_name, send_meth, expect_success, args,
- ret_val_meth) in send_methods:
- indata = (data_prefix + meth_name).encode('ascii')
- try:
- ret = send_meth(indata, *args)
- msg = "sending with {}".format(meth_name)
- self.assertEqual(ret, ret_val_meth(indata), msg=msg)
- outdata = s.read()
- if outdata != indata.lower():
- self.fail(
- "While sending with <<{name:s}>> bad data "
- "<<{outdata:r}>> ({nout:d}) received; "
- "expected <<{indata:r}>> ({nin:d})\n".format(
- name=meth_name, outdata=outdata[:20],
- nout=len(outdata),
- indata=indata[:20], nin=len(indata)
- )
- )
- except ValueError as e:
- if expect_success:
- self.fail(
- "Failed to send with method <<{name:s}>>; "
- "expected to succeed.\n".format(name=meth_name)
+ def test_recv_send(self):
+ """Test recv(), send() and friends."""
+ if support.verbose:
+ sys.stdout.write("\n")
+
+ server = ThreadedEchoServer(CERTFILE,
+ certreqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ cacerts=CERTFILE,
+ chatty=True,
+ connectionchatty=False)
+ with server:
+ s = test_wrap_socket(socket.socket(),
+ server_side=False,
+ certfile=CERTFILE,
+ ca_certs=CERTFILE,
+ cert_reqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1)
+ s.connect((HOST, server.port))
+ # helper methods for standardising recv* method signatures
+ def _recv_into():
+ b = bytearray(b"\0"*100)
+ count = s.recv_into(b)
+ return b[:count]
+
+ def _recvfrom_into():
+ b = bytearray(b"\0"*100)
+ count, addr = s.recvfrom_into(b)
+ return b[:count]
+
+ # (name, method, expect success?, *args, return value func)
+ send_methods = [
+ ('send', s.send, True, [], len),
+ ('sendto', s.sendto, False, ["some.address"], len),
+ ('sendall', s.sendall, True, [], lambda x: None),
+ ]
+ # (name, method, whether to expect success, *args)
+ recv_methods = [
+ ('recv', s.recv, True, []),
+ ('recvfrom', s.recvfrom, False, ["some.address"]),
+ ('recv_into', _recv_into, True, []),
+ ('recvfrom_into', _recvfrom_into, False, []),
+ ]
+ data_prefix = "PREFIX_"
+
+ for (meth_name, send_meth, expect_success, args,
+ ret_val_meth) in send_methods:
+ indata = (data_prefix + meth_name).encode('ascii')
+ try:
+ ret = send_meth(indata, *args)
+ msg = "sending with {}".format(meth_name)
+ self.assertEqual(ret, ret_val_meth(indata), msg=msg)
+ outdata = s.read()
+ if outdata != indata.lower():
+ self.fail(
+ "While sending with <<{name:s}>> bad data "
+ "<<{outdata:r}>> ({nout:d}) received; "
+ "expected <<{indata:r}>> ({nin:d})\n".format(
+ name=meth_name, outdata=outdata[:20],
+ nout=len(outdata),
+ indata=indata[:20], nin=len(indata)
)
- if not str(e).startswith(meth_name):
- self.fail(
- "Method <<{name:s}>> failed with unexpected "
- "exception message: {exp:s}\n".format(
- name=meth_name, exp=e
- )
+ )
+ except ValueError as e:
+ if expect_success:
+ self.fail(
+ "Failed to send with method <<{name:s}>>; "
+ "expected to succeed.\n".format(name=meth_name)
+ )
+ if not str(e).startswith(meth_name):
+ self.fail(
+ "Method <<{name:s}>> failed with unexpected "
+ "exception message: {exp:s}\n".format(
+ name=meth_name, exp=e
)
+ )
- for meth_name, recv_meth, expect_success, args in recv_methods:
- indata = (data_prefix + meth_name).encode('ascii')
- try:
- s.send(indata)
- outdata = recv_meth(*args)
- if outdata != indata.lower():
- self.fail(
- "While receiving with <<{name:s}>> bad data "
- "<<{outdata:r}>> ({nout:d}) received; "
- "expected <<{indata:r}>> ({nin:d})\n".format(
- name=meth_name, outdata=outdata[:20],
- nout=len(outdata),
- indata=indata[:20], nin=len(indata)
- )
- )
- except ValueError as e:
- if expect_success:
- self.fail(
- "Failed to receive with method <<{name:s}>>; "
- "expected to succeed.\n".format(name=meth_name)
+ for meth_name, recv_meth, expect_success, args in recv_methods:
+ indata = (data_prefix + meth_name).encode('ascii')
+ try:
+ s.send(indata)
+ outdata = recv_meth(*args)
+ if outdata != indata.lower():
+ self.fail(
+ "While receiving with <<{name:s}>> bad data "
+ "<<{outdata:r}>> ({nout:d}) received; "
+ "expected <<{indata:r}>> ({nin:d})\n".format(
+ name=meth_name, outdata=outdata[:20],
+ nout=len(outdata),
+ indata=indata[:20], nin=len(indata)
)
- if not str(e).startswith(meth_name):
- self.fail(
- "Method <<{name:s}>> failed with unexpected "
- "exception message: {exp:s}\n".format(
- name=meth_name, exp=e
- )
+ )
+ except ValueError as e:
+ if expect_success:
+ self.fail(
+ "Failed to receive with method <<{name:s}>>; "
+ "expected to succeed.\n".format(name=meth_name)
+ )
+ if not str(e).startswith(meth_name):
+ self.fail(
+ "Method <<{name:s}>> failed with unexpected "
+ "exception message: {exp:s}\n".format(
+ name=meth_name, exp=e
)
- # consume data
- s.read()
+ )
+ # consume data
+ s.read()
- # read(-1, buffer) is supported, even though read(-1) is not
- data = b"data"
- s.send(data)
- buffer = bytearray(len(data))
- self.assertEqual(s.read(-1, buffer), len(data))
- self.assertEqual(buffer, data)
+ # read(-1, buffer) is supported, even though read(-1) is not
+ data = b"data"
+ s.send(data)
+ buffer = bytearray(len(data))
+ self.assertEqual(s.read(-1, buffer), len(data))
+ self.assertEqual(buffer, data)
- # Make sure sendmsg et al are disallowed to avoid
- # inadvertent disclosure of data and/or corruption
- # of the encrypted data stream
- self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
- self.assertRaises(NotImplementedError, s.recvmsg, 100)
- self.assertRaises(NotImplementedError,
- s.recvmsg_into, bytearray(100))
+ # Make sure sendmsg et al are disallowed to avoid
+ # inadvertent disclosure of data and/or corruption
+ # of the encrypted data stream
+ self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
+ self.assertRaises(NotImplementedError, s.recvmsg, 100)
+ self.assertRaises(NotImplementedError,
+ s.recvmsg_into, bytearray(100))
- s.write(b"over\n")
+ s.write(b"over\n")
- self.assertRaises(ValueError, s.recv, -1)
- self.assertRaises(ValueError, s.read, -1)
+ self.assertRaises(ValueError, s.recv, -1)
+ self.assertRaises(ValueError, s.read, -1)
- s.close()
+ s.close()
- def test_recv_zero(self):
- server = ThreadedEchoServer(CERTFILE)
- server.__enter__()
- self.addCleanup(server.__exit__, None, None)
- s = socket.create_connection((HOST, server.port))
- self.addCleanup(s.close)
- s = test_wrap_socket(s, suppress_ragged_eofs=False)
- self.addCleanup(s.close)
+ def test_recv_zero(self):
+ server = ThreadedEchoServer(CERTFILE)
+ server.__enter__()
+ self.addCleanup(server.__exit__, None, None)
+ s = socket.create_connection((HOST, server.port))
+ self.addCleanup(s.close)
+ s = test_wrap_socket(s, suppress_ragged_eofs=False)
+ self.addCleanup(s.close)
- # recv/read(0) should return no data
- s.send(b"data")
- self.assertEqual(s.recv(0), b"")
- self.assertEqual(s.read(0), b"")
- self.assertEqual(s.read(), b"data")
+ # recv/read(0) should return no data
+ s.send(b"data")
+ self.assertEqual(s.recv(0), b"")
+ self.assertEqual(s.read(0), b"")
+ self.assertEqual(s.read(), b"data")
+
+ # Should not block if the other end sends no data
+ s.setblocking(False)
+ self.assertEqual(s.recv(0), b"")
+ self.assertEqual(s.recv_into(bytearray()), 0)
- # Should not block if the other end sends no data
+ def test_nonblocking_send(self):
+ server = ThreadedEchoServer(CERTFILE,
+ certreqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ cacerts=CERTFILE,
+ chatty=True,
+ connectionchatty=False)
+ with server:
+ s = test_wrap_socket(socket.socket(),
+ server_side=False,
+ certfile=CERTFILE,
+ ca_certs=CERTFILE,
+ cert_reqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1)
+ s.connect((HOST, server.port))
s.setblocking(False)
- self.assertEqual(s.recv(0), b"")
- self.assertEqual(s.recv_into(bytearray()), 0)
-
- def test_nonblocking_send(self):
- server = ThreadedEchoServer(CERTFILE,
- certreqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1,
- cacerts=CERTFILE,
- chatty=True,
- connectionchatty=False)
- with server:
- s = test_wrap_socket(socket.socket(),
- server_side=False,
- certfile=CERTFILE,
- ca_certs=CERTFILE,
- cert_reqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1)
- s.connect((HOST, server.port))
- s.setblocking(False)
-
- # If we keep sending data, at some point the buffers
- # will be full and the call will block
- buf = bytearray(8192)
- def fill_buffer():
- while True:
- s.send(buf)
- self.assertRaises((ssl.SSLWantWriteError,
- ssl.SSLWantReadError), fill_buffer)
-
- # Now read all the output and discard it
- s.setblocking(True)
- s.close()
- def test_handshake_timeout(self):
- # Issue #5103: SSL handshake must respect the socket timeout
- server = socket.socket(socket.AF_INET)
- host = "127.0.0.1"
- port = support.bind_port(server)
- started = threading.Event()
- finish = False
-
- def serve():
- server.listen()
- started.set()
- conns = []
- while not finish:
- r, w, e = select.select([server], [], [], 0.1)
- if server in r:
- # Let the socket hang around rather than having
- # it closed by garbage collection.
- conns.append(server.accept()[0])
- for sock in conns:
- sock.close()
-
- t = threading.Thread(target=serve)
- t.start()
- started.wait()
+ # If we keep sending data, at some point the buffers
+ # will be full and the call will block
+ buf = bytearray(8192)
+ def fill_buffer():
+ while True:
+ s.send(buf)
+ self.assertRaises((ssl.SSLWantWriteError,
+ ssl.SSLWantReadError), fill_buffer)
+
+ # Now read all the output and discard it
+ s.setblocking(True)
+ s.close()
+
+ def test_handshake_timeout(self):
+ # Issue #5103: SSL handshake must respect the socket timeout
+ server = socket.socket(socket.AF_INET)
+ host = "127.0.0.1"
+ port = support.bind_port(server)
+ started = threading.Event()
+ finish = False
+
+ def serve():
+ server.listen()
+ started.set()
+ conns = []
+ while not finish:
+ r, w, e = select.select([server], [], [], 0.1)
+ if server in r:
+ # Let the socket hang around rather than having
+ # it closed by garbage collection.
+ conns.append(server.accept()[0])
+ for sock in conns:
+ sock.close()
+
+ t = threading.Thread(target=serve)
+ t.start()
+ started.wait()
+ try:
try:
- try:
- c = socket.socket(socket.AF_INET)
- c.settimeout(0.2)
- c.connect((host, port))
- # Will attempt handshake and time out
- self.assertRaisesRegex(socket.timeout, "timed out",
- test_wrap_socket, c)
- finally:
- c.close()
- try:
- c = socket.socket(socket.AF_INET)
- c = test_wrap_socket(c)
- c.settimeout(0.2)
- # Will attempt handshake and time out
- self.assertRaisesRegex(socket.timeout, "timed out",
- c.connect, (host, port))
- finally:
- c.close()
+ c = socket.socket(socket.AF_INET)
+ c.settimeout(0.2)
+ c.connect((host, port))
+ # Will attempt handshake and time out
+ self.assertRaisesRegex(socket.timeout, "timed out",
+ test_wrap_socket, c)
finally:
- finish = True
- t.join()
- server.close()
-
- def test_server_accept(self):
- # Issue #16357: accept() on a SSLSocket created through
- # SSLContext.wrap_socket().
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(CERTFILE)
- context.load_cert_chain(CERTFILE)
- server = socket.socket(socket.AF_INET)
- host = "127.0.0.1"
- port = support.bind_port(server)
- server = context.wrap_socket(server, server_side=True)
- self.assertTrue(server.server_side)
-
- evt = threading.Event()
- remote = None
- peer = None
- def serve():
- nonlocal remote, peer
- server.listen()
- # Block on the accept and wait on the connection to close.
- evt.set()
- remote, peer = server.accept()
- remote.recv(1)
-
- t = threading.Thread(target=serve)
- t.start()
- # Client wait until server setup and perform a connect.
- evt.wait()
- client = context.wrap_socket(socket.socket())
- client.connect((host, port))
- client_addr = client.getsockname()
- client.close()
+ c.close()
+ try:
+ c = socket.socket(socket.AF_INET)
+ c = test_wrap_socket(c)
+ c.settimeout(0.2)
+ # Will attempt handshake and time out
+ self.assertRaisesRegex(socket.timeout, "timed out",
+ c.connect, (host, port))
+ finally:
+ c.close()
+ finally:
+ finish = True
t.join()
- remote.close()
server.close()
- # Sanity checks.
- self.assertIsInstance(remote, ssl.SSLSocket)
- self.assertEqual(peer, client_addr)
-
- def test_getpeercert_enotconn(self):
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- with context.wrap_socket(socket.socket()) as sock:
- with self.assertRaises(OSError) as cm:
- sock.getpeercert()
- self.assertEqual(cm.exception.errno, errno.ENOTCONN)
-
- def test_do_handshake_enotconn(self):
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- with context.wrap_socket(socket.socket()) as sock:
- with self.assertRaises(OSError) as cm:
- sock.do_handshake()
- self.assertEqual(cm.exception.errno, errno.ENOTCONN)
-
- def test_default_ciphers(self):
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- try:
- # Force a set of weak ciphers on our client context
- context.set_ciphers("DES")
- except ssl.SSLError:
- self.skipTest("no DES cipher available")
- with ThreadedEchoServer(CERTFILE,
- ssl_version=ssl.PROTOCOL_SSLv23,
- chatty=False) as server:
- with context.wrap_socket(socket.socket()) as s:
- with self.assertRaises(OSError):
- s.connect((HOST, server.port))
- self.assertIn("no shared cipher", server.conn_errors[0])
-
- def test_version_basic(self):
- """
- Basic tests for SSLSocket.version().
- More tests are done in the test_protocol_*() methods.
- """
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- with ThreadedEchoServer(CERTFILE,
- ssl_version=ssl.PROTOCOL_TLSv1,
- chatty=False) as server:
- with context.wrap_socket(socket.socket()) as s:
- self.assertIs(s.version(), None)
- s.connect((HOST, server.port))
- self.assertEqual(s.version(), 'TLSv1')
- self.assertIs(s.version(), None)
- @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
- def test_default_ecdh_curve(self):
- # Issue #21015: elliptic curve-based Diffie Hellman key exchange
- # should be enabled by default on SSL contexts.
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.load_cert_chain(CERTFILE)
- # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
- # explicitly using the 'ECCdraft' cipher alias. Otherwise,
- # our default cipher list should prefer ECDH-based ciphers
- # automatically.
- if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
- context.set_ciphers("ECCdraft:ECDH")
- with ThreadedEchoServer(context=context) as server:
- with context.wrap_socket(socket.socket()) as s:
+ def test_server_accept(self):
+ # Issue #16357: accept() on a SSLSocket created through
+ # SSLContext.wrap_socket().
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(CERTFILE)
+ context.load_cert_chain(CERTFILE)
+ server = socket.socket(socket.AF_INET)
+ host = "127.0.0.1"
+ port = support.bind_port(server)
+ server = context.wrap_socket(server, server_side=True)
+ self.assertTrue(server.server_side)
+
+ evt = threading.Event()
+ remote = None
+ peer = None
+ def serve():
+ nonlocal remote, peer
+ server.listen()
+ # Block on the accept and wait on the connection to close.
+ evt.set()
+ remote, peer = server.accept()
+ remote.recv(1)
+
+ t = threading.Thread(target=serve)
+ t.start()
+ # Client wait until server setup and perform a connect.
+ evt.wait()
+ client = context.wrap_socket(socket.socket())
+ client.connect((host, port))
+ client_addr = client.getsockname()
+ client.close()
+ t.join()
+ remote.close()
+ server.close()
+ # Sanity checks.
+ self.assertIsInstance(remote, ssl.SSLSocket)
+ self.assertEqual(peer, client_addr)
+
+ def test_getpeercert_enotconn(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ with context.wrap_socket(socket.socket()) as sock:
+ with self.assertRaises(OSError) as cm:
+ sock.getpeercert()
+ self.assertEqual(cm.exception.errno, errno.ENOTCONN)
+
+ def test_do_handshake_enotconn(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ with context.wrap_socket(socket.socket()) as sock:
+ with self.assertRaises(OSError) as cm:
+ sock.do_handshake()
+ self.assertEqual(cm.exception.errno, errno.ENOTCONN)
+
+ def test_default_ciphers(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ try:
+ # Force a set of weak ciphers on our client context
+ context.set_ciphers("DES")
+ except ssl.SSLError:
+ self.skipTest("no DES cipher available")
+ with ThreadedEchoServer(CERTFILE,
+ ssl_version=ssl.PROTOCOL_SSLv23,
+ chatty=False) as server:
+ with context.wrap_socket(socket.socket()) as s:
+ with self.assertRaises(OSError):
s.connect((HOST, server.port))
- self.assertIn("ECDH", s.cipher()[0])
+ self.assertIn("no shared cipher", server.conn_errors[0])
- @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
- "'tls-unique' channel binding not available")
- def test_tls_unique_channel_binding(self):
- """Test tls-unique channel binding."""
- if support.verbose:
- sys.stdout.write("\n")
-
- server = ThreadedEchoServer(CERTFILE,
- certreqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1,
- cacerts=CERTFILE,
- chatty=True,
- connectionchatty=False)
- with server:
- s = test_wrap_socket(socket.socket(),
- server_side=False,
- certfile=CERTFILE,
- ca_certs=CERTFILE,
- cert_reqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1)
+ def test_version_basic(self):
+ """
+ Basic tests for SSLSocket.version().
+ More tests are done in the test_protocol_*() methods.
+ """
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ with ThreadedEchoServer(CERTFILE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ chatty=False) as server:
+ with context.wrap_socket(socket.socket()) as s:
+ self.assertIs(s.version(), None)
s.connect((HOST, server.port))
- # get the data
- cb_data = s.get_channel_binding("tls-unique")
- if support.verbose:
- sys.stdout.write(" got channel binding data: {0!r}\n"
- .format(cb_data))
-
- # check if it is sane
- self.assertIsNotNone(cb_data)
- self.assertEqual(len(cb_data), 12) # True for TLSv1
-
- # and compare with the peers version
- s.write(b"CB tls-unique\n")
- peer_data_repr = s.read().strip()
- self.assertEqual(peer_data_repr,
- repr(cb_data).encode("us-ascii"))
- s.close()
-
- # now, again
- s = test_wrap_socket(socket.socket(),
- server_side=False,
- certfile=CERTFILE,
- ca_certs=CERTFILE,
- cert_reqs=ssl.CERT_NONE,
- ssl_version=ssl.PROTOCOL_TLSv1)
+ self.assertEqual(s.version(), 'TLSv1')
+ self.assertIs(s.version(), None)
+
+ @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
+ def test_default_ecdh_curve(self):
+ # Issue #21015: elliptic curve-based Diffie Hellman key exchange
+ # should be enabled by default on SSL contexts.
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.load_cert_chain(CERTFILE)
+ # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
+ # explicitly using the 'ECCdraft' cipher alias. Otherwise,
+ # our default cipher list should prefer ECDH-based ciphers
+ # automatically.
+ if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
+ context.set_ciphers("ECCdraft:ECDH")
+ with ThreadedEchoServer(context=context) as server:
+ with context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
- new_cb_data = s.get_channel_binding("tls-unique")
- if support.verbose:
- sys.stdout.write(" got another channel binding data: {0!r}\n"
- .format(new_cb_data))
- # is it really unique
- self.assertNotEqual(cb_data, new_cb_data)
- self.assertIsNotNone(cb_data)
- self.assertEqual(len(cb_data), 12) # True for TLSv1
- s.write(b"CB tls-unique\n")
- peer_data_repr = s.read().strip()
- self.assertEqual(peer_data_repr,
- repr(new_cb_data).encode("us-ascii"))
- s.close()
+ self.assertIn("ECDH", s.cipher()[0])
- def test_compression(self):
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.load_cert_chain(CERTFILE)
- stats = server_params_test(context, context,
- chatty=True, connectionchatty=True)
- if support.verbose:
- sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
- self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
-
- @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
- "ssl.OP_NO_COMPRESSION needed for this test")
- def test_compression_disabled(self):
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.load_cert_chain(CERTFILE)
- context.options |= ssl.OP_NO_COMPRESSION
- stats = server_params_test(context, context,
- chatty=True, connectionchatty=True)
- self.assertIs(stats['compression'], None)
-
- def test_dh_params(self):
- # Check we can get a connection with ephemeral Diffie-Hellman
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.load_cert_chain(CERTFILE)
- context.load_dh_params(DHFILE)
- context.set_ciphers("kEDH")
- stats = server_params_test(context, context,
- chatty=True, connectionchatty=True)
- cipher = stats["cipher"][0]
- parts = cipher.split("-")
- if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
- self.fail("Non-DH cipher: " + cipher[0])
-
- def test_selected_alpn_protocol(self):
- # selected_alpn_protocol() is None unless ALPN is used.
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.load_cert_chain(CERTFILE)
- stats = server_params_test(context, context,
- chatty=True, connectionchatty=True)
- self.assertIs(stats['client_alpn_protocol'], None)
+ @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
+ "'tls-unique' channel binding not available")
+ def test_tls_unique_channel_binding(self):
+ """Test tls-unique channel binding."""
+ if support.verbose:
+ sys.stdout.write("\n")
- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
- def test_selected_alpn_protocol_if_server_uses_alpn(self):
- # selected_alpn_protocol() is None unless ALPN is used by the client.
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- client_context.load_verify_locations(CERTFILE)
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server = ThreadedEchoServer(CERTFILE,
+ certreqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ cacerts=CERTFILE,
+ chatty=True,
+ connectionchatty=False)
+ with server:
+ s = test_wrap_socket(socket.socket(),
+ server_side=False,
+ certfile=CERTFILE,
+ ca_certs=CERTFILE,
+ cert_reqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1)
+ s.connect((HOST, server.port))
+ # get the data
+ cb_data = s.get_channel_binding("tls-unique")
+ if support.verbose:
+ sys.stdout.write(" got channel binding data: {0!r}\n"
+ .format(cb_data))
+
+ # check if it is sane
+ self.assertIsNotNone(cb_data)
+ self.assertEqual(len(cb_data), 12) # True for TLSv1
+
+ # and compare with the peers version
+ s.write(b"CB tls-unique\n")
+ peer_data_repr = s.read().strip()
+ self.assertEqual(peer_data_repr,
+ repr(cb_data).encode("us-ascii"))
+ s.close()
+
+ # now, again
+ s = test_wrap_socket(socket.socket(),
+ server_side=False,
+ certfile=CERTFILE,
+ ca_certs=CERTFILE,
+ cert_reqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1)
+ s.connect((HOST, server.port))
+ new_cb_data = s.get_channel_binding("tls-unique")
+ if support.verbose:
+ sys.stdout.write(" got another channel binding data: {0!r}\n"
+ .format(new_cb_data))
+ # is it really unique
+ self.assertNotEqual(cb_data, new_cb_data)
+ self.assertIsNotNone(cb_data)
+ self.assertEqual(len(cb_data), 12) # True for TLSv1
+ s.write(b"CB tls-unique\n")
+ peer_data_repr = s.read().strip()
+ self.assertEqual(peer_data_repr,
+ repr(new_cb_data).encode("us-ascii"))
+ s.close()
+
+ def test_compression(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ if support.verbose:
+ sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
+ self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
+
+ @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
+ "ssl.OP_NO_COMPRESSION needed for this test")
+ def test_compression_disabled(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ context.options |= ssl.OP_NO_COMPRESSION
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['compression'], None)
+
+ def test_dh_params(self):
+ # Check we can get a connection with ephemeral Diffie-Hellman
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ context.load_dh_params(DHFILE)
+ context.set_ciphers("kEDH")
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ cipher = stats["cipher"][0]
+ parts = cipher.split("-")
+ if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
+ self.fail("Non-DH cipher: " + cipher[0])
+
+ def test_selected_alpn_protocol(self):
+ # selected_alpn_protocol() is None unless ALPN is used.
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['client_alpn_protocol'], None)
+
+ @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
+ def test_selected_alpn_protocol_if_server_uses_alpn(self):
+ # selected_alpn_protocol() is None unless ALPN is used by the client.
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.load_verify_locations(CERTFILE)
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(CERTFILE)
+ server_context.set_alpn_protocols(['foo', 'bar'])
+ stats = server_params_test(client_context, server_context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['client_alpn_protocol'], None)
+
+ @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
+ def test_alpn_protocols(self):
+ server_protocols = ['foo', 'bar', 'milkshake']
+ protocol_tests = [
+ (['foo', 'bar'], 'foo'),
+ (['bar', 'foo'], 'foo'),
+ (['milkshake'], 'milkshake'),
+ (['http/3.0', 'http/4.0'], None)
+ ]
+ for client_protocols, expected in protocol_tests:
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
server_context.load_cert_chain(CERTFILE)
- server_context.set_alpn_protocols(['foo', 'bar'])
- stats = server_params_test(client_context, server_context,
- chatty=True, connectionchatty=True)
- self.assertIs(stats['client_alpn_protocol'], None)
-
- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
- def test_alpn_protocols(self):
- server_protocols = ['foo', 'bar', 'milkshake']
- protocol_tests = [
- (['foo', 'bar'], 'foo'),
- (['bar', 'foo'], 'foo'),
- (['milkshake'], 'milkshake'),
- (['http/3.0', 'http/4.0'], None)
- ]
- for client_protocols, expected in protocol_tests:
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
- server_context.load_cert_chain(CERTFILE)
- server_context.set_alpn_protocols(server_protocols)
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
- client_context.load_cert_chain(CERTFILE)
- client_context.set_alpn_protocols(client_protocols)
+ server_context.set_alpn_protocols(server_protocols)
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
+ client_context.load_cert_chain(CERTFILE)
+ client_context.set_alpn_protocols(client_protocols)
- try:
- stats = server_params_test(client_context,
- server_context,
- chatty=True,
- connectionchatty=True)
- except ssl.SSLError as e:
- stats = e
-
- if (expected is None and IS_OPENSSL_1_1
- and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)):
- # OpenSSL 1.1.0 to 1.1.0e raises handshake error
- self.assertIsInstance(stats, ssl.SSLError)
- else:
- msg = "failed trying %s (s) and %s (c).\n" \
- "was expecting %s, but got %%s from the %%s" \
- % (str(server_protocols), str(client_protocols),
- str(expected))
- client_result = stats['client_alpn_protocol']
- self.assertEqual(client_result, expected,
- msg % (client_result, "client"))
- server_result = stats['server_alpn_protocols'][-1] \
- if len(stats['server_alpn_protocols']) else 'nothing'
- self.assertEqual(server_result, expected,
- msg % (server_result, "server"))
-
- def test_selected_npn_protocol(self):
- # selected_npn_protocol() is None unless NPN is used
- context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- context.load_cert_chain(CERTFILE)
- stats = server_params_test(context, context,
- chatty=True, connectionchatty=True)
- self.assertIs(stats['client_npn_protocol'], None)
-
- @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
- def test_npn_protocols(self):
- server_protocols = ['http/1.1', 'spdy/2']
- protocol_tests = [
- (['http/1.1', 'spdy/2'], 'http/1.1'),
- (['spdy/2', 'http/1.1'], 'http/1.1'),
- (['spdy/2', 'test'], 'spdy/2'),
- (['abc', 'def'], 'abc')
- ]
- for client_protocols, expected in protocol_tests:
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(CERTFILE)
- server_context.set_npn_protocols(server_protocols)
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- client_context.load_cert_chain(CERTFILE)
- client_context.set_npn_protocols(client_protocols)
- stats = server_params_test(client_context, server_context,
- chatty=True, connectionchatty=True)
+ try:
+ stats = server_params_test(client_context,
+ server_context,
+ chatty=True,
+ connectionchatty=True)
+ except ssl.SSLError as e:
+ stats = e
+ if (expected is None and IS_OPENSSL_1_1
+ and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)):
+ # OpenSSL 1.1.0 to 1.1.0e raises handshake error
+ self.assertIsInstance(stats, ssl.SSLError)
+ else:
msg = "failed trying %s (s) and %s (c).\n" \
- "was expecting %s, but got %%s from the %%s" \
- % (str(server_protocols), str(client_protocols),
- str(expected))
- client_result = stats['client_npn_protocol']
- self.assertEqual(client_result, expected, msg % (client_result, "client"))
- server_result = stats['server_npn_protocols'][-1] \
- if len(stats['server_npn_protocols']) else 'nothing'
- self.assertEqual(server_result, expected, msg % (server_result, "server"))
-
- def sni_contexts(self):
+ "was expecting %s, but got %%s from the %%s" \
+ % (str(server_protocols), str(client_protocols),
+ str(expected))
+ client_result = stats['client_alpn_protocol']
+ self.assertEqual(client_result, expected,
+ msg % (client_result, "client"))
+ server_result = stats['server_alpn_protocols'][-1] \
+ if len(stats['server_alpn_protocols']) else 'nothing'
+ self.assertEqual(server_result, expected,
+ msg % (server_result, "server"))
+
+ def test_selected_npn_protocol(self):
+ # selected_npn_protocol() is None unless NPN is used
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['client_npn_protocol'], None)
+
+ @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
+ def test_npn_protocols(self):
+ server_protocols = ['http/1.1', 'spdy/2']
+ protocol_tests = [
+ (['http/1.1', 'spdy/2'], 'http/1.1'),
+ (['spdy/2', 'http/1.1'], 'http/1.1'),
+ (['spdy/2', 'test'], 'spdy/2'),
+ (['abc', 'def'], 'abc')
+ ]
+ for client_protocols, expected in protocol_tests:
server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(SIGNED_CERTFILE)
- other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- other_context.load_cert_chain(SIGNED_CERTFILE2)
+ server_context.load_cert_chain(CERTFILE)
+ server_context.set_npn_protocols(server_protocols)
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- client_context.verify_mode = ssl.CERT_REQUIRED
- client_context.load_verify_locations(SIGNING_CA)
- return server_context, other_context, client_context
+ client_context.load_cert_chain(CERTFILE)
+ client_context.set_npn_protocols(client_protocols)
+ stats = server_params_test(client_context, server_context,
+ chatty=True, connectionchatty=True)
- def check_common_name(self, stats, name):
- cert = stats['peercert']
- self.assertIn((('commonName', name),), cert['subject'])
+ msg = "failed trying %s (s) and %s (c).\n" \
+ "was expecting %s, but got %%s from the %%s" \
+ % (str(server_protocols), str(client_protocols),
+ str(expected))
+ client_result = stats['client_npn_protocol']
+ self.assertEqual(client_result, expected, msg % (client_result, "client"))
+ server_result = stats['server_npn_protocols'][-1] \
+ if len(stats['server_npn_protocols']) else 'nothing'
+ self.assertEqual(server_result, expected, msg % (server_result, "server"))
+
+ def sni_contexts(self):
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ other_context.load_cert_chain(SIGNED_CERTFILE2)
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.verify_mode = ssl.CERT_REQUIRED
+ client_context.load_verify_locations(SIGNING_CA)
+ return server_context, other_context, client_context
+
+ def check_common_name(self, stats, name):
+ cert = stats['peercert']
+ self.assertIn((('commonName', name),), cert['subject'])
+
+ @needs_sni
+ def test_sni_callback(self):
+ calls = []
+ server_context, other_context, client_context = self.sni_contexts()
+
+ def servername_cb(ssl_sock, server_name, initial_context):
+ calls.append((server_name, initial_context))
+ if server_name is not None:
+ ssl_sock.context = other_context
+ server_context.set_servername_callback(servername_cb)
+
+ stats = server_params_test(client_context, server_context,
+ chatty=True,
+ sni_name='supermessage')
+ # The hostname was fetched properly, and the certificate was
+ # changed for the connection.
+ self.assertEqual(calls, [("supermessage", server_context)])
+ # CERTFILE4 was selected
+ self.check_common_name(stats, 'fakehostname')
+
+ calls = []
+ # The callback is called with server_name=None
+ stats = server_params_test(client_context, server_context,
+ chatty=True,
+ sni_name=None)
+ self.assertEqual(calls, [(None, server_context)])
+ self.check_common_name(stats, 'localhost')
+
+ # Check disabling the callback
+ calls = []
+ server_context.set_servername_callback(None)
+
+ stats = server_params_test(client_context, server_context,
+ chatty=True,
+ sni_name='notfunny')
+ # Certificate didn't change
+ self.check_common_name(stats, 'localhost')
+ self.assertEqual(calls, [])
- @needs_sni
- def test_sni_callback(self):
- calls = []
- server_context, other_context, client_context = self.sni_contexts()
+ @needs_sni
+ def test_sni_callback_alert(self):
+ # Returning a TLS alert is reflected to the connecting client
+ server_context, other_context, client_context = self.sni_contexts()
- def servername_cb(ssl_sock, server_name, initial_context):
- calls.append((server_name, initial_context))
- if server_name is not None:
- ssl_sock.context = other_context
- server_context.set_servername_callback(servername_cb)
+ def cb_returning_alert(ssl_sock, server_name, initial_context):
+ return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
+ server_context.set_servername_callback(cb_returning_alert)
+ with self.assertRaises(ssl.SSLError) as cm:
stats = server_params_test(client_context, server_context,
- chatty=True,
+ chatty=False,
sni_name='supermessage')
- # The hostname was fetched properly, and the certificate was
- # changed for the connection.
- self.assertEqual(calls, [("supermessage", server_context)])
- # CERTFILE4 was selected
- self.check_common_name(stats, 'fakehostname')
-
- calls = []
- # The callback is called with server_name=None
+ self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
+
+ @needs_sni
+ def test_sni_callback_raising(self):
+ # Raising fails the connection with a TLS handshake failure alert.
+ server_context, other_context, client_context = self.sni_contexts()
+
+ def cb_raising(ssl_sock, server_name, initial_context):
+ 1/0
+ server_context.set_servername_callback(cb_raising)
+
+ with self.assertRaises(ssl.SSLError) as cm, \
+ support.captured_stderr() as stderr:
stats = server_params_test(client_context, server_context,
- chatty=True,
- sni_name=None)
- self.assertEqual(calls, [(None, server_context)])
- self.check_common_name(stats, 'localhost')
+ chatty=False,
+ sni_name='supermessage')
+ self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
+ self.assertIn("ZeroDivisionError", stderr.getvalue())
+
+ @needs_sni
+ def test_sni_callback_wrong_return_type(self):
+ # Returning the wrong return type terminates the TLS connection
+ # with an internal error alert.
+ server_context, other_context, client_context = self.sni_contexts()
- # Check disabling the callback
- calls = []
- server_context.set_servername_callback(None)
+ def cb_wrong_return_type(ssl_sock, server_name, initial_context):
+ return "foo"
+ server_context.set_servername_callback(cb_wrong_return_type)
+ with self.assertRaises(ssl.SSLError) as cm, \
+ support.captured_stderr() as stderr:
stats = server_params_test(client_context, server_context,
- chatty=True,
- sni_name='notfunny')
- # Certificate didn't change
- self.check_common_name(stats, 'localhost')
- self.assertEqual(calls, [])
-
- @needs_sni
- def test_sni_callback_alert(self):
- # Returning a TLS alert is reflected to the connecting client
- server_context, other_context, client_context = self.sni_contexts()
-
- def cb_returning_alert(ssl_sock, server_name, initial_context):
- return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
- server_context.set_servername_callback(cb_returning_alert)
-
- with self.assertRaises(ssl.SSLError) as cm:
- stats = server_params_test(client_context, server_context,
- chatty=False,
- sni_name='supermessage')
- self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
-
- @needs_sni
- def test_sni_callback_raising(self):
- # Raising fails the connection with a TLS handshake failure alert.
- server_context, other_context, client_context = self.sni_contexts()
-
- def cb_raising(ssl_sock, server_name, initial_context):
- 1/0
- server_context.set_servername_callback(cb_raising)
-
- with self.assertRaises(ssl.SSLError) as cm, \
- support.captured_stderr() as stderr:
- stats = server_params_test(client_context, server_context,
- chatty=False,
- sni_name='supermessage')
- self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
- self.assertIn("ZeroDivisionError", stderr.getvalue())
-
- @needs_sni
- def test_sni_callback_wrong_return_type(self):
- # Returning the wrong return type terminates the TLS connection
- # with an internal error alert.
- server_context, other_context, client_context = self.sni_contexts()
-
- def cb_wrong_return_type(ssl_sock, server_name, initial_context):
- return "foo"
- server_context.set_servername_callback(cb_wrong_return_type)
-
- with self.assertRaises(ssl.SSLError) as cm, \
- support.captured_stderr() as stderr:
- stats = server_params_test(client_context, server_context,
- chatty=False,
- sni_name='supermessage')
- self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
- self.assertIn("TypeError", stderr.getvalue())
-
- def test_shared_ciphers(self):
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(SIGNED_CERTFILE)
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- client_context.verify_mode = ssl.CERT_REQUIRED
- client_context.load_verify_locations(SIGNING_CA)
- if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
- client_context.set_ciphers("AES128:AES256")
- server_context.set_ciphers("AES256")
- alg1 = "AES256"
- alg2 = "AES-256"
- else:
- client_context.set_ciphers("AES:3DES")
- server_context.set_ciphers("3DES")
- alg1 = "3DES"
- alg2 = "DES-CBC3"
-
- stats = server_params_test(client_context, server_context)
- ciphers = stats['server_shared_ciphers'][0]
- self.assertGreater(len(ciphers), 0)
- for name, tls_version, bits in ciphers:
- if not alg1 in name.split("-") and alg2 not in name:
- self.fail(name)
-
- def test_read_write_after_close_raises_valuerror(self):
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(CERTFILE)
- context.load_cert_chain(CERTFILE)
- server = ThreadedEchoServer(context=context, chatty=False)
-
- with server:
- s = context.wrap_socket(socket.socket())
+ chatty=False,
+ sni_name='supermessage')
+ self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
+ self.assertIn("TypeError", stderr.getvalue())
+
+ def test_shared_ciphers(self):
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.verify_mode = ssl.CERT_REQUIRED
+ client_context.load_verify_locations(SIGNING_CA)
+ if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
+ client_context.set_ciphers("AES128:AES256")
+ server_context.set_ciphers("AES256")
+ alg1 = "AES256"
+ alg2 = "AES-256"
+ else:
+ client_context.set_ciphers("AES:3DES")
+ server_context.set_ciphers("3DES")
+ alg1 = "3DES"
+ alg2 = "DES-CBC3"
+
+ stats = server_params_test(client_context, server_context)
+ ciphers = stats['server_shared_ciphers'][0]
+ self.assertGreater(len(ciphers), 0)
+ for name, tls_version, bits in ciphers:
+ if not alg1 in name.split("-") and alg2 not in name:
+ self.fail(name)
+
+ def test_read_write_after_close_raises_valuerror(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(CERTFILE)
+ context.load_cert_chain(CERTFILE)
+ server = ThreadedEchoServer(context=context, chatty=False)
+
+ with server:
+ s = context.wrap_socket(socket.socket())
+ s.connect((HOST, server.port))
+ s.close()
+
+ self.assertRaises(ValueError, s.read, 1024)
+ self.assertRaises(ValueError, s.write, b'hello')
+
+ def test_sendfile(self):
+ TEST_DATA = b"x" * 512
+ with open(support.TESTFN, 'wb') as f:
+ f.write(TEST_DATA)
+ self.addCleanup(support.unlink, support.TESTFN)
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(CERTFILE)
+ context.load_cert_chain(CERTFILE)
+ server = ThreadedEchoServer(context=context, chatty=False)
+ with server:
+ with context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
- s.close()
+ with open(support.TESTFN, 'rb') as file:
+ s.sendfile(file)
+ self.assertEqual(s.recv(1024), TEST_DATA)
+
+ def test_session(self):
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.verify_mode = ssl.CERT_REQUIRED
+ client_context.load_verify_locations(SIGNING_CA)
+
+ # first connection without session
+ stats = server_params_test(client_context, server_context)
+ session = stats['session']
+ self.assertTrue(session.id)
+ self.assertGreater(session.time, 0)
+ self.assertGreater(session.timeout, 0)
+ self.assertTrue(session.has_ticket)
+ if ssl.OPENSSL_VERSION_INFO > (1, 0, 1):
+ self.assertGreater(session.ticket_lifetime_hint, 0)
+ self.assertFalse(stats['session_reused'])
+ sess_stat = server_context.session_stats()
+ self.assertEqual(sess_stat['accept'], 1)
+ self.assertEqual(sess_stat['hits'], 0)
+
+ # reuse session
+ stats = server_params_test(client_context, server_context, session=session)
+ sess_stat = server_context.session_stats()
+ self.assertEqual(sess_stat['accept'], 2)
+ self.assertEqual(sess_stat['hits'], 1)
+ self.assertTrue(stats['session_reused'])
+ session2 = stats['session']
+ self.assertEqual(session2.id, session.id)
+ self.assertEqual(session2, session)
+ self.assertIsNot(session2, session)
+ self.assertGreaterEqual(session2.time, session.time)
+ self.assertGreaterEqual(session2.timeout, session.timeout)
+
+ # another one without session
+ stats = server_params_test(client_context, server_context)
+ self.assertFalse(stats['session_reused'])
+ session3 = stats['session']
+ self.assertNotEqual(session3.id, session.id)
+ self.assertNotEqual(session3, session)
+ sess_stat = server_context.session_stats()
+ self.assertEqual(sess_stat['accept'], 3)
+ self.assertEqual(sess_stat['hits'], 1)
+
+ # reuse session again
+ stats = server_params_test(client_context, server_context, session=session)
+ self.assertTrue(stats['session_reused'])
+ session4 = stats['session']
+ self.assertEqual(session4.id, session.id)
+ self.assertEqual(session4, session)
+ self.assertGreaterEqual(session4.time, session.time)
+ self.assertGreaterEqual(session4.timeout, session.timeout)
+ sess_stat = server_context.session_stats()
+ self.assertEqual(sess_stat['accept'], 4)
+ self.assertEqual(sess_stat['hits'], 2)
+
+ def test_session_handling(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.load_verify_locations(CERTFILE)
+ context.load_cert_chain(CERTFILE)
+
+ context2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ context2.verify_mode = ssl.CERT_REQUIRED
+ context2.load_verify_locations(CERTFILE)
+ context2.load_cert_chain(CERTFILE)
+
+ server = ThreadedEchoServer(context=context, chatty=False)
+ with server:
+ with context.wrap_socket(socket.socket()) as s:
+ # session is None before handshake
+ self.assertEqual(s.session, None)
+ self.assertEqual(s.session_reused, None)
+ s.connect((HOST, server.port))
+ session = s.session
+ self.assertTrue(session)
+ with self.assertRaises(TypeError) as e:
+ s.session = object
+ self.assertEqual(str(e.exception), 'Value is not a SSLSession.')
- self.assertRaises(ValueError, s.read, 1024)
- self.assertRaises(ValueError, s.write, b'hello')
-
- def test_sendfile(self):
- TEST_DATA = b"x" * 512
- with open(support.TESTFN, 'wb') as f:
- f.write(TEST_DATA)
- self.addCleanup(support.unlink, support.TESTFN)
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(CERTFILE)
- context.load_cert_chain(CERTFILE)
- server = ThreadedEchoServer(context=context, chatty=False)
- with server:
- with context.wrap_socket(socket.socket()) as s:
- s.connect((HOST, server.port))
- with open(support.TESTFN, 'rb') as file:
- s.sendfile(file)
- self.assertEqual(s.recv(1024), TEST_DATA)
+ with context.wrap_socket(socket.socket()) as s:
+ s.connect((HOST, server.port))
+ # cannot set session after handshake
+ with self.assertRaises(ValueError) as e:
+ s.session = session
+ self.assertEqual(str(e.exception),
+ 'Cannot set session after handshake.')
- def test_session(self):
- server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- server_context.load_cert_chain(SIGNED_CERTFILE)
- client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
- client_context.verify_mode = ssl.CERT_REQUIRED
- client_context.load_verify_locations(SIGNING_CA)
-
- # first connection without session
- stats = server_params_test(client_context, server_context)
- session = stats['session']
- self.assertTrue(session.id)
- self.assertGreater(session.time, 0)
- self.assertGreater(session.timeout, 0)
- self.assertTrue(session.has_ticket)
- if ssl.OPENSSL_VERSION_INFO > (1, 0, 1):
- self.assertGreater(session.ticket_lifetime_hint, 0)
- self.assertFalse(stats['session_reused'])
- sess_stat = server_context.session_stats()
- self.assertEqual(sess_stat['accept'], 1)
- self.assertEqual(sess_stat['hits'], 0)
-
- # reuse session
- stats = server_params_test(client_context, server_context, session=session)
- sess_stat = server_context.session_stats()
- self.assertEqual(sess_stat['accept'], 2)
- self.assertEqual(sess_stat['hits'], 1)
- self.assertTrue(stats['session_reused'])
- session2 = stats['session']
- self.assertEqual(session2.id, session.id)
- self.assertEqual(session2, session)
- self.assertIsNot(session2, session)
- self.assertGreaterEqual(session2.time, session.time)
- self.assertGreaterEqual(session2.timeout, session.timeout)
-
- # another one without session
- stats = server_params_test(client_context, server_context)
- self.assertFalse(stats['session_reused'])
- session3 = stats['session']
- self.assertNotEqual(session3.id, session.id)
- self.assertNotEqual(session3, session)
- sess_stat = server_context.session_stats()
- self.assertEqual(sess_stat['accept'], 3)
- self.assertEqual(sess_stat['hits'], 1)
-
- # reuse session again
- stats = server_params_test(client_context, server_context, session=session)
- self.assertTrue(stats['session_reused'])
- session4 = stats['session']
- self.assertEqual(session4.id, session.id)
- self.assertEqual(session4, session)
- self.assertGreaterEqual(session4.time, session.time)
- self.assertGreaterEqual(session4.timeout, session.timeout)
- sess_stat = server_context.session_stats()
- self.assertEqual(sess_stat['accept'], 4)
- self.assertEqual(sess_stat['hits'], 2)
-
- def test_session_handling(self):
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context.verify_mode = ssl.CERT_REQUIRED
- context.load_verify_locations(CERTFILE)
- context.load_cert_chain(CERTFILE)
-
- context2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- context2.verify_mode = ssl.CERT_REQUIRED
- context2.load_verify_locations(CERTFILE)
- context2.load_cert_chain(CERTFILE)
-
- server = ThreadedEchoServer(context=context, chatty=False)
- with server:
- with context.wrap_socket(socket.socket()) as s:
- # session is None before handshake
- self.assertEqual(s.session, None)
- self.assertEqual(s.session_reused, None)
- s.connect((HOST, server.port))
- session = s.session
- self.assertTrue(session)
- with self.assertRaises(TypeError) as e:
- s.session = object
- self.assertEqual(str(e.exception), 'Value is not a SSLSession.')
+ with context.wrap_socket(socket.socket()) as s:
+ # can set session before handshake and before the
+ # connection was established
+ s.session = session
+ s.connect((HOST, server.port))
+ self.assertEqual(s.session.id, session.id)
+ self.assertEqual(s.session, session)
+ self.assertEqual(s.session_reused, True)
- with context.wrap_socket(socket.socket()) as s:
- s.connect((HOST, server.port))
- # cannot set session after handshake
- with self.assertRaises(ValueError) as e:
- s.session = session
- self.assertEqual(str(e.exception),
- 'Cannot set session after handshake.')
-
- with context.wrap_socket(socket.socket()) as s:
- # can set session before handshake and before the
- # connection was established
+ with context2.wrap_socket(socket.socket()) as s:
+ # cannot re-use session with a different SSLContext
+ with self.assertRaises(ValueError) as e:
s.session = session
s.connect((HOST, server.port))
- self.assertEqual(s.session.id, session.id)
- self.assertEqual(s.session, session)
- self.assertEqual(s.session_reused, True)
-
- with context2.wrap_socket(socket.socket()) as s:
- # cannot re-use session with a different SSLContext
- with self.assertRaises(ValueError) as e:
- s.session = session
- s.connect((HOST, server.port))
- self.assertEqual(str(e.exception),
- 'Session refers to a different SSLContext.')
+ self.assertEqual(str(e.exception),
+ 'Session refers to a different SSLContext.')
def test_main(verbose=False):
tests = [
ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
- SimpleBackgroundTests,
+ SimpleBackgroundTests, ThreadedTests,
]
if support.is_resource_enabled('network'):
tests.append(NetworkedTests)
- if _have_threads:
- thread_info = support.threading_setup()
- if thread_info:
- tests.append(ThreadedTests)
-
+ thread_info = support.threading_setup()
try:
support.run_unittest(*tests)
finally:
- if _have_threads:
- support.threading_cleanup(*thread_info)
+ support.threading_cleanup(*thread_info)
if __name__ == "__main__":
test_main()
import sysconfig
import select
import shutil
+import threading
import gc
import textwrap
else:
import ctypes.util
-try:
- import threading
-except ImportError:
- threading = None
-
try:
import _testcapi
except ImportError:
self.assertEqual(stderr, "")
self.assertEqual(proc.returncode, 0)
- @unittest.skipIf(threading is None, "threading required")
def test_double_close_on_error(self):
# Issue #18851
fds = []
if exc is not None:
raise exc
- @unittest.skipIf(threading is None, "threading required")
def test_threadsafe_wait(self):
"""Issue21291: Popen.wait() needs to be threadsafe for returncode."""
proc = subprocess.Popen([sys.executable, '-c',
import gc
import sysconfig
import locale
+import threading
# count the number of test runs, used to create unique
# strings to intern in test_intern()
numruns = 0
-try:
- import threading
-except ImportError:
- threading = None
class SysModuleTest(unittest.TestCase):
sys.setcheckinterval(n)
self.assertEqual(sys.getcheckinterval(), n)
- @unittest.skipUnless(threading, 'Threading required for this test.')
def test_switchinterval(self):
self.assertRaises(TypeError, sys.setswitchinterval)
self.assertRaises(TypeError, sys.setswitchinterval, "a")
)
# 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
- def current_frames_with_threads(self):
+ def test_current_frames(self):
import threading
import traceback
leave_g.set()
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):
self.assertIsInstance(sys.api_version, int)
self.assertIsInstance(sys.argv, list)
if not sys.platform.startswith('win'):
self.assertIsInstance(sys.abiflags, str)
- @unittest.skipUnless(hasattr(sys, 'thread_info'),
- 'Threading required for this test.')
def test_thread_info(self):
info = sys.thread_info
self.assertEqual(len(info), 3)
import socket
import selectors
import telnetlib
+import threading
import contextlib
from test import support
import unittest
-threading = support.import_module('threading')
HOST = support.HOST
import sys
import time
import shutil
+import threading
import unittest
from unittest import mock
from test.support import (
verbose, import_module, run_unittest, TESTFN, reap_threads,
forget, unlink, rmtree, start_threads)
-threading = import_module('threading')
def task(N, done, done_tasks, errors):
try:
import tempfile
from test.support import start_threads, import_module
-threading = import_module('threading')
import unittest
import io
+import threading
from traceback import print_exc
startEvent = threading.Event()
import random
import sys
-_thread = import_module('_thread')
-threading = import_module('threading')
+import _thread
+import threading
import time
import unittest
import weakref
import gc
# Modules under test
-_thread = support.import_module('_thread')
-threading = support.import_module('threading')
+import _thread
+import threading
import _threading_local
import sysconfig
import time
import unittest
-try:
- import threading
-except ImportError:
- threading = None
try:
import _testcapi
except ImportError:
from test.support.script_helper import (assert_python_ok, assert_python_failure,
interpreter_requires_environment)
from test import support
-try:
- import threading
-except ImportError:
- threading = None
+
try:
import _testcapi
except ImportError:
import urllib.parse
import urllib.request
import http.server
+import threading
import unittest
import hashlib
from test import support
-threading = support.import_module('threading')
-
try:
import ssl
except ImportError:
# Test cases
-@unittest.skipUnless(threading, "Threading required for this test.")
class BasicAuthTests(unittest.TestCase):
USER = "testUser"
PASSWD = "testPass"
self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url)
-@unittest.skipUnless(threading, "Threading required for this test.")
class ProxyAuthTests(unittest.TestCase):
URL = "http://localhost"
return FakeHTTPRequestHandler
-@unittest.skipUnless(threading, "Threading required for this test.")
class TestUrlopen(unittest.TestCase):
"""Tests urllib.request.urlopen using the network.
import tempfile
from test.support import (captured_stdout, captured_stderr,
can_symlink, EnvironmentVarGuard, rmtree)
+import threading
import unittest
import venv
-
-try:
- import threading
-except ImportError:
- threading = None
-
try:
import ctypes
except ImportError:
if not system_site_packages:
self.assert_pip_not_installed()
- @unittest.skipUnless(threading, 'some dependencies of pip import threading'
- ' module unconditionally')
# Issue #26610: pip/pep425tags.py requires ctypes
@unittest.skipUnless(ctypes, 'pip requires ctypes')
def test_with_pip(self):
import operator
import contextlib
import copy
+import threading
import time
from test import support
"""
Ensure GC collections happen in a different thread, at a high frequency.
"""
- threading = support.import_module('threading')
please_stop = False
def collect():
import http.client
import http, http.server
import socket
+import threading
import re
import io
import contextlib
import gzip
except ImportError:
gzip = None
-try:
- import threading
-except ImportError:
- threading = None
alist = [{'astring': 'foo@bar.baz.spam',
'afloat': 7283.43,
except OSError:
self.assertTrue(has_ssl)
- @unittest.skipUnless(threading, "Threading required for this test.")
def test_keepalive_disconnect(self):
class RequestHandler(http.server.BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
return make_request_and_skip
return decorator
-@unittest.skipUnless(threading, 'Threading required for this test.')
class BaseServerTestCase(unittest.TestCase):
requestHandler = None
request_count = 1
return super().get(key, failobj)
-@unittest.skipUnless(threading, 'Threading required for this test.')
class FailingServerTestCase(unittest.TestCase):
def setUp(self):
self.evt = threading.Event()
def _delete(self):
"Remove current thread from the dict of currently running threads."
-
- # Notes about running with _dummy_thread:
- #
- # Must take care to not raise an exception if _dummy_thread is being
- # used (and thus this module is being used as an instance of
- # dummy_threading). _dummy_thread.get_ident() always returns 1 since
- # 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
+ 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.
def join(self, timeout=None):
"""Wait until the thread terminates.
import pickle
from time import monotonic as _time
-try:
- import threading
-except ImportError:
- _settrace = sys.settrace
-
- def _unsettrace():
- sys.settrace(None)
-else:
- def _settrace(func):
- threading.settrace(func)
- sys.settrace(func)
-
- def _unsettrace():
- sys.settrace(None)
- threading.settrace(None)
+import threading
+
+def _settrace(func):
+ threading.settrace(func)
+ sys.settrace(func)
+
+def _unsettrace():
+ sys.settrace(None)
+ threading.settrace(None)
PRAGMA_NOCOVER = "#pragma NO COVER"
import shutil
import struct
import binascii
-
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
+import threading
try:
import zlib # We may need its compression method
SYSLIBS= $(LIBM) $(LIBC)
SHLIBS= @SHLIBS@
-THREADOBJ= @THREADOBJ@
DLINCLDIR= @DLINCLDIR@
DYNLOADFILE= @DYNLOADFILE@
MACHDEP_OBJS= @MACHDEP_OBJS@
Python/structmember.o \
Python/symtable.o \
Python/sysmodule.o \
+ Python/thread.o \
Python/traceback.o \
Python/getopt.o \
Python/pystrcmp.o \
Python/$(DYNLOADFILE) \
$(LIBOBJS) \
$(MACHDEP_OBJS) \
- $(THREADOBJ) \
$(DTRACE_OBJS)
Makefile Modules/config.c: Makefile.pre \
$(srcdir)/Modules/config.c.in \
$(MAKESETUP) \
- Modules/Setup.config \
Modules/Setup \
Modules/Setup.local
$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
-s Modules \
- Modules/Setup.config \
Modules/Setup.local \
Modules/Setup
@mv config.c Modules
$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
$(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
$(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_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \
done
-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 \
Misc/python-config.sh
-rm -f python*-gdb.py
--- /dev/null
+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.
+++ /dev/null
-# 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.
_signal signalmodule.c
_stat _stat.c # stat.h interface
time timemodule.c # -lm # time operations and variables
+_thread _threadmodule.c # low-level threading interface
# access to ISO C locale support
_locale _localemodule.c # -lintl
# The crypt module is now disabled by default because it breaks builds
# 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
# Curses support, requiring the System V version of curses, often
# provided by the ncurses library. e.g. on Linux, link with -lncurses
# instead of -lcurses).
-#
-# First, look at Setup.config; configure may have set this for you.
#_curses _cursesmodule.c -lcurses -ltermcap
# Wrapper for the panel library that's part of ncurses and SYSV curses.
# implementation independent wrapper for these; dbm/dumb.py provides
# 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
# 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
#include "Python.h"
#include "pystrhex.h"
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif
#include "../hashlib.h"
#include "blake2ns.h"
PyObject_HEAD
blake2b_param param;
blake2b_state state;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} BLAKE2bObject;
#include "clinic/blake2b_impl.c.h"
{
BLAKE2bObject *self;
self = (BLAKE2bObject *)type->tp_alloc(type, 0);
-#ifdef WITH_THREAD
if (self != NULL) {
self->lock = NULL;
}
-#endif
return self;
}
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
-#ifdef WITH_THREAD
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
self->lock = PyThread_allocate_lock();
} else {
blake2b_update(&self->state, buf.buf, buf.len);
}
-#else
- blake2b_update(&self->state, buf.buf, buf.len);
-#endif /* !WITH_THREAD */
PyBuffer_Release(&buf);
Py_RETURN_NONE;
/* Try not to leave state in memory. */
secure_zero_memory(&obj->param, sizeof(obj->param));
secure_zero_memory(&obj->state, sizeof(obj->state));
-#ifdef WITH_THREAD
if (obj->lock) {
PyThread_free_lock(obj->lock);
obj->lock = NULL;
}
-#endif
PyObject_Del(self);
}
#include "Python.h"
#include "pystrhex.h"
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif
#include "../hashlib.h"
#include "blake2ns.h"
PyObject_HEAD
blake2s_param param;
blake2s_state state;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} BLAKE2sObject;
#include "clinic/blake2s_impl.c.h"
{
BLAKE2sObject *self;
self = (BLAKE2sObject *)type->tp_alloc(type, 0);
-#ifdef WITH_THREAD
if (self != NULL) {
self->lock = NULL;
}
-#endif
return self;
}
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
-#ifdef WITH_THREAD
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
self->lock = PyThread_allocate_lock();
} else {
blake2s_update(&self->state, buf.buf, buf.len);
}
-#else
- blake2s_update(&self->state, buf.buf, buf.len);
-#endif /* !WITH_THREAD */
PyBuffer_Release(&buf);
Py_RETURN_NONE;
/* Try not to leave state in memory. */
secure_zero_memory(&obj->param, sizeof(obj->param));
secure_zero_memory(&obj->state, sizeof(obj->state));
-#ifdef WITH_THREAD
if (obj->lock) {
PyThread_free_lock(obj->lock);
obj->lock = NULL;
}
-#endif
PyObject_Del(self);
}
#include "Python.h"
#include "structmember.h"
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif
#include <bzlib.h>
#include <stdio.h>
#endif /* ! BZ_CONFIG_ERROR */
-#ifdef WITH_THREAD
#define ACQUIRE_LOCK(obj) do { \
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
Py_BEGIN_ALLOW_THREADS \
Py_END_ALLOW_THREADS \
} } while (0)
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
-#else
-#define ACQUIRE_LOCK(obj)
-#define RELEASE_LOCK(obj)
-#endif
typedef struct {
PyObject_HEAD
bz_stream bzs;
int flushed;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} BZ2Compressor;
typedef struct {
separately. Conversion and looping is encapsulated in
decompress_buf() */
size_t bzs_avail_in_real;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} BZ2Decompressor;
static PyTypeObject BZ2Compressor_Type;
return -1;
}
-#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
return -1;
}
-#endif
self->bzs.opaque = NULL;
self->bzs.bzalloc = BZ2_Malloc;
return 0;
error:
-#ifdef WITH_THREAD
PyThread_free_lock(self->lock);
self->lock = NULL;
-#endif
return -1;
}
BZ2Compressor_dealloc(BZ2Compressor *self)
{
BZ2_bzCompressEnd(&self->bzs);
-#ifdef WITH_THREAD
if (self->lock != NULL)
PyThread_free_lock(self->lock);
-#endif
Py_TYPE(self)->tp_free((PyObject *)self);
}
{
int bzerror;
-#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
return -1;
}
-#endif
self->needs_input = 1;
self->bzs_avail_in_real = 0;
error:
Py_CLEAR(self->unused_data);
-#ifdef WITH_THREAD
PyThread_free_lock(self->lock);
self->lock = NULL;
-#endif
return -1;
}
PyMem_Free(self->input_buffer);
BZ2_bzDecompressEnd(&self->bzs);
Py_CLEAR(self->unused_data);
-#ifdef WITH_THREAD
if (self->lock != NULL)
PyThread_free_lock(self->lock);
-#endif
Py_TYPE(self)->tp_free((PyObject *)self);
}
ob_type is the metatype (the 'type'), defaults to PyType_Type,
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
*/
-#ifdef WITH_THREAD
PyEval_InitThreads();
-#endif
m = PyModule_Create(&_ctypesmodule);
if (!m)
return NULL;
Py_ssize_t nArgs;
PyObject *error_object = NULL;
int *space;
-#ifdef WITH_THREAD
PyGILState_STATE state = PyGILState_Ensure();
-#endif
nArgs = PySequence_Length(converters);
/* Hm. What to return in case of error?
Py_XDECREF(result);
Done:
Py_XDECREF(arglist);
-#ifdef WITH_THREAD
PyGILState_Release(state);
-#endif
}
static void closure_fcn(ffi_cif *cif,
assert(CThunk_CheckExact((PyObject *)p));
p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
- &p->pcl_exec);
+ &p->pcl_exec);
if (p->pcl_write == NULL) {
PyErr_NoMemory();
goto error;
result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
#else
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
- p,
- p->pcl_exec);
+ p,
+ p->pcl_exec);
#endif
if (result != FFI_OK) {
PyErr_Format(PyExc_RuntimeError,
static void LoadPython(void)
{
if (!Py_IsInitialized()) {
-#ifdef WITH_THREAD
PyEval_InitThreads();
-#endif
Py_Initialize();
}
}
LPVOID *ppv)
{
long result;
-#ifdef WITH_THREAD
PyGILState_STATE state;
-#endif
LoadPython();
-#ifdef WITH_THREAD
state = PyGILState_Ensure();
-#endif
result = Call_GetClassObject(rclsid, riid, ppv);
-#ifdef WITH_THREAD
PyGILState_Release(state);
-#endif
return result;
}
STDAPI DllCanUnloadNow(void)
{
long result;
-#ifdef WITH_THREAD
PyGILState_STATE state = PyGILState_Ensure();
-#endif
result = Call_CanUnloadNow();
-#ifdef WITH_THREAD
PyGILState_Release(state);
-#endif
return result;
}
void *resmem,
int argcount)
{
-#ifdef WITH_THREAD
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
-#endif
PyObject *error_object = NULL;
int *space;
ffi_cif cif;
if (error_object == NULL)
return -1;
}
-#ifdef WITH_THREAD
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_UNBLOCK_THREADS
-#endif
if (flags & FUNCFLAG_USE_ERRNO) {
int temp = space[0];
space[0] = errno;
space[0] = errno;
errno = temp;
}
-#ifdef WITH_THREAD
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
-#endif
Py_XDECREF(error_object);
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
/* We absolutely have to release the GIL during COM method calls,
otherwise we may get a deadlock!
*/
-#ifdef WITH_THREAD
Py_BEGIN_ALLOW_THREADS
-#endif
hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
if (FAILED(hr))
pei->lpVtbl->Release(pei);
failed:
-#ifdef WITH_THREAD
Py_END_ALLOW_THREADS
-#endif
progid = NULL;
ProgIDFromCLSID(&guid, &progid);
PyObject_HEAD
PyObject *name; /* name of this hash algorithm */
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
-#ifdef WITH_THREAD
PyThread_type_lock lock; /* OpenSSL context lock */
-#endif
} EVPobject;
/* save the name for .name to return */
Py_INCREF(name);
retval->name = name;
-#ifdef WITH_THREAD
retval->lock = NULL;
-#endif
return retval;
}
static void
EVP_dealloc(EVPobject *self)
{
-#ifdef WITH_THREAD
if (self->lock != NULL)
PyThread_free_lock(self->lock);
-#endif
EVP_MD_CTX_free(self->ctx);
Py_XDECREF(self->name);
PyObject_Del(self);
GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
-#ifdef WITH_THREAD
if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
self->lock = PyThread_allocate_lock();
/* fail? lock = NULL and we fail over to non-threaded code. */
} else {
EVP_hash(self, view.buf, view.len);
}
-#else
- EVP_hash(self, view.buf, view.len);
-#endif
PyBuffer_Release(&view);
Py_RETURN_NONE;
isn't ready for writing. */
Py_off_t write_end;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
volatile unsigned long owner;
-#endif
Py_ssize_t buffer_size;
Py_ssize_t buffer_mask;
/* These macros protect the buffered object against concurrent operations. */
-#ifdef WITH_THREAD
-
static int
_enter_buffered_busy(buffered *self)
{
PyThread_release_lock(self->lock); \
} while(0);
-#else
-#define ENTER_BUFFERED(self) 1
-#define LEAVE_BUFFERED(self)
-#endif
-
#define CHECK_INITIALIZED(self) \
if (self->ok <= 0) { \
if (self->detached) { \
PyMem_Free(self->buffer);
self->buffer = NULL;
}
-#ifdef WITH_THREAD
if (self->lock) {
PyThread_free_lock(self->lock);
self->lock = NULL;
}
-#endif
Py_CLEAR(self->dict);
Py_TYPE(self)->tp_free((PyObject *)self);
}
PyErr_NoMemory();
return -1;
}
-#ifdef WITH_THREAD
if (self->lock)
PyThread_free_lock(self->lock);
self->lock = PyThread_allocate_lock();
return -1;
}
self->owner = 0;
-#endif
/* Find out whether buffer_size is a power of 2 */
/* XXX is this optimization useful? */
for (n = self->buffer_size - 1; n & 1; n >>= 1)
#include "Python.h"
#include "structmember.h"
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif
#include <stdarg.h>
#include <string.h>
#include <lzma.h>
-#ifdef WITH_THREAD
#define ACQUIRE_LOCK(obj) do { \
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
Py_BEGIN_ALLOW_THREADS \
Py_END_ALLOW_THREADS \
} } while (0)
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
-#else
-#define ACQUIRE_LOCK(obj)
-#define RELEASE_LOCK(obj)
-#endif
/* Container formats: */
lzma_allocator alloc;
lzma_stream lzs;
int flushed;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} Compressor;
typedef struct {
char needs_input;
uint8_t *input_buffer;
size_t input_buffer_size;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} Decompressor;
/* LZMAError class object. */
self->alloc.free = PyLzma_Free;
self->lzs.allocator = &self->alloc;
-#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
return -1;
}
-#endif
self->flushed = 0;
switch (format) {
break;
}
-#ifdef WITH_THREAD
PyThread_free_lock(self->lock);
self->lock = NULL;
-#endif
return -1;
}
Compressor_dealloc(Compressor *self)
{
lzma_end(&self->lzs);
-#ifdef WITH_THREAD
if (self->lock != NULL)
PyThread_free_lock(self->lock);
-#endif
Py_TYPE(self)->tp_free((PyObject *)self);
}
self->lzs.allocator = &self->alloc;
self->lzs.next_in = NULL;
-#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
return -1;
}
-#endif
self->check = LZMA_CHECK_UNKNOWN;
self->needs_input = 1;
error:
Py_CLEAR(self->unused_data);
-#ifdef WITH_THREAD
PyThread_free_lock(self->lock);
self->lock = NULL;
-#endif
return -1;
}
lzma_end(&self->lzs);
Py_CLEAR(self->unused_data);
-#ifdef WITH_THREAD
if (self->lock != NULL)
PyThread_free_lock(self->lock);
-#endif
Py_TYPE(self)->tp_free((PyObject *)self);
}
typedef struct {
PyObject_HEAD
SHA3_state hash_state;
-#ifdef WITH_THREAD
PyThread_type_lock lock;
-#endif
} SHA3object;
static PyTypeObject SHA3_224type;
if (newobj == NULL) {
return NULL;
}
-#ifdef WITH_THREAD
newobj->lock = NULL;
-#endif
return newobj;
}
if (data) {
GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
-#ifdef WITH_THREAD
if (buf.len >= HASHLIB_GIL_MINSIZE) {
/* invariant: New objects can't be accessed by other code yet,
* thus it's safe to release the GIL without locking the object.
else {
res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
}
-#else
- res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
-#endif
if (res != SUCCESS) {
PyErr_SetString(PyExc_RuntimeError,
"internal error in SHA3 Update()");
static void
SHA3_dealloc(SHA3object *self)
{
-#ifdef WITH_THREAD
if (self->lock) {
PyThread_free_lock(self->lock);
}
-#endif
PyObject_Del(self);
}
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
/* add new data, the function takes the length in bits not bytes */
-#ifdef WITH_THREAD
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) {
self->lock = PyThread_allocate_lock();
}
else {
res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
}
-#else
- res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8);
-#endif
if (res != SUCCESS) {
PyBuffer_Release(&buf);
self->detect_types = detect_types;
self->timeout = timeout;
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
-#ifdef WITH_THREAD
self->thread_ident = PyThread_get_thread_ident();
-#endif
if (!check_same_thread && sqlite3_libversion_number() < 3003001) {
PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available");
return -1;
PyObject* py_retval = NULL;
int ok;
-#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
-#endif
py_func = (PyObject*)sqlite3_user_data(context);
_sqlite3_result_error(context, "user-defined function raised exception", -1);
}
-#ifdef WITH_THREAD
PyGILState_Release(threadstate);
-#endif
}
static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
PyObject** aggregate_instance;
PyObject* stepmethod = NULL;
-#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
-#endif
aggregate_class = (PyObject*)sqlite3_user_data(context);
Py_XDECREF(stepmethod);
Py_XDECREF(function_result);
-#ifdef WITH_THREAD
PyGILState_Release(threadstate);
-#endif
}
void _pysqlite_final_callback(sqlite3_context* context)
PyObject *exception, *value, *tb;
int restore;
-#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
-#endif
aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
if (!*aggregate_instance) {
}
error:
-#ifdef WITH_THREAD
PyGILState_Release(threadstate);
-#endif
- /* explicit return to avoid a compilation error if WITH_THREAD
- is not defined */
- return;
}
static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
{
PyObject *ret;
int rc;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
-#endif
ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
Py_DECREF(ret);
}
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return rc;
}
{
int rc;
PyObject *ret;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
-#endif
ret = _PyObject_CallNoArg((PyObject*)user_arg);
if (!ret) {
Py_DECREF(ret);
}
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return rc;
}
PyObject *py_statement = NULL;
PyObject *ret = NULL;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
-#endif
py_statement = PyUnicode_DecodeUTF8(statement_string,
strlen(statement_string), "replace");
if (py_statement) {
}
}
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
}
static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
int pysqlite_check_thread(pysqlite_Connection* self)
{
-#ifdef WITH_THREAD
if (self->check_same_thread) {
if (PyThread_get_thread_ident() != self->thread_ident) {
PyErr_Format(pysqlite_ProgrammingError,
}
}
-#endif
return 1;
}
PyObject* callback = (PyObject*)context;
PyObject* string1 = 0;
PyObject* string2 = 0;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate;
-#endif
PyObject* retval = NULL;
long longval;
int result = 0;
-#ifdef WITH_THREAD
gilstate = PyGILState_Ensure();
-#endif
if (PyErr_Occurred()) {
goto finally;
Py_XDECREF(string1);
Py_XDECREF(string2);
Py_XDECREF(retval);
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return result;
}
* threads have already been initialized.
* (see pybsddb-users mailing list post on 2002-08-07)
*/
-#ifdef WITH_THREAD
PyEval_InitThreads();
-#endif
error:
if (PyErr_Occurred())
#include "Python.h"
-#ifdef WITH_THREAD
#include "pythread.h"
/* Redefined below for Windows debug builds after important #includes */
#define PySSL_UNBLOCK_THREADS PySSL_BEGIN_ALLOW_THREADS_S(_save);
#define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); }
-#else /* no WITH_THREAD */
-
-#define PySSL_BEGIN_ALLOW_THREADS_S(save)
-#define PySSL_END_ALLOW_THREADS_S(save)
-#define PySSL_BEGIN_ALLOW_THREADS
-#define PySSL_BLOCK_THREADS
-#define PySSL_UNBLOCK_THREADS
-#define PySSL_END_ALLOW_THREADS
-
-#endif
-
/* Include symbols from _socket module */
#include "socketmodule.h"
#define OPENSSL_NO_SSL2
#endif
#else /* OpenSSL < 1.1.0 */
-#if defined(WITH_THREAD)
#define HAVE_OPENSSL_CRYPTO_LOCK
-#endif
#define TLS_method SSLv23_method
#define TLS_client_method SSLv23_client_method
PY_SSL_VERSION_TLS_SERVER,
};
-#ifdef WITH_THREAD
-
/* serves as a flag to see whether we've initialized the SSL thread support. */
/* 0 means no, greater than 0 means yes */
static unsigned int _ssl_locks_count = 0;
-#endif /* def WITH_THREAD */
-
/* SSL socket object */
#define X509_NAME_MAXLEN 256
/* The high-level ssl.SSLSocket object */
PyObject *ssl_socket;
const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
-#ifdef WITH_THREAD
PyGILState_STATE gstate = PyGILState_Ensure();
-#endif
if (ssl_ctx->set_hostname == NULL) {
/* remove race condition in this the call back while if removing the
* callback is in progress */
-#ifdef WITH_THREAD
PyGILState_Release(gstate);
-#endif
return SSL_TLSEXT_ERR_OK;
}
Py_DECREF(result);
}
-#ifdef WITH_THREAD
PyGILState_Release(gstate);
-#endif
return ret;
error:
Py_DECREF(ssl_socket);
*al = SSL_AD_INTERNAL_ERROR;
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-#ifdef WITH_THREAD
PyGILState_Release(gstate);
-#endif
return ret;
}
#endif
return 1;
}
-#endif /* HAVE_OPENSSL_CRYPTO_LOCK for WITH_THREAD && OpenSSL < 1.1.0 */
+#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */
PyDoc_STRVAR(module_doc,
"Implementation module for SSL socket operations. See the socket module\n\
SSL_library_init();
#endif
-#ifdef WITH_THREAD
#ifdef HAVE_OPENSSL_CRYPTO_LOCK
/* note that this will start threading if not already started */
if (!_setup_ssl_threads()) {
/* OpenSSL 1.1.0 builtin thread support is enabled */
_ssl_locks_count++;
#endif
-#endif /* WITH_THREAD */
/* Add symbols to module dict */
sslerror_type_slots[0].pfunc = PyExc_OSError;
#include <sys/wait.h> /* For W_STOPCODE */
#endif
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif /* WITH_THREAD */
static PyObject *TestError; /* set to exception object in init */
/* Raise TestError with test_name + ": " + msg, and return NULL. */
}
-#ifdef WITH_THREAD
-
/* test_thread_state spawns a thread of its own, and that thread releases
* `thread_done` when it's finished. The driver code has to know when the
* thread finishes, because the thread uses a PyObject (the callable) that
}
Py_RETURN_TRUE;
}
-#endif
/* Some tests of PyUnicode_FromFormat(). This needs more tests. */
static PyObject *
"and the parameters take defaults of varying types."
);
-#ifdef WITH_THREAD
typedef struct {
PyThread_type_lock start_event;
PyThread_type_lock exit_event;
PyThread_free_lock(test_c_thread.exit_event);
return res;
}
-#endif /* WITH_THREAD */
static PyObject*
test_raise_signal(PyObject* self, PyObject *args)
{"unicode_encodedecimal", unicode_encodedecimal, METH_VARARGS},
{"unicode_transformdecimaltoascii", unicode_transformdecimaltoascii, METH_VARARGS},
{"unicode_legacy_string", unicode_legacy_string, METH_VARARGS},
-#ifdef WITH_THREAD
{"_test_thread_state", test_thread_state, METH_VARARGS},
{"_pending_threadfunc", pending_threadfunc, METH_VARARGS},
-#endif
#ifdef HAVE_GETTIMEOFDAY
{"profile_int", profile_int, METH_NOARGS},
#endif
docstring_with_signature_with_defaults},
{"raise_signal",
(PyCFunction)test_raise_signal, METH_VARARGS},
-#ifdef WITH_THREAD
{"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O,
PyDoc_STR("set_error_class(error_class) -> None")},
-#endif
{"pymarshal_write_long_to_file",
pymarshal_write_long_to_file, METH_VARARGS},
{"pymarshal_write_object_to_file",
#include "Python.h"
#include "structmember.h" /* offsetof */
-
-#ifndef WITH_THREAD
-#error "Error! The rest of Python is not compiled with thread support."
-#error "Rerun configure, adding a --with-threads option."
-#error "Then run `make clean' followed by `make'."
-#endif
-
#include "pythread.h"
static PyObject *ThreadError;
#include "Python.h"
#include <ctype.h>
-#ifdef WITH_THREAD
#include "pythread.h"
-#endif
#ifdef MS_WINDOWS
#include <windows.h>
}
#endif /* MS_WINDOWS */
-#ifdef WITH_THREAD
-
/* The threading situation is complicated. Tcl is not thread-safe, except
when configured with --enable-threads.
return 0; \
}
-#else
-
-#define ENTER_TCL
-#define LEAVE_TCL
-#define ENTER_OVERLAP
-#define LEAVE_OVERLAP_TCL
-#define ENTER_PYTHON
-#define LEAVE_PYTHON
-#define CHECK_TCL_APPARTMENT
-
-#endif
-
#ifndef FREECAST
#define FREECAST (char *)
#endif
static int Tkinter_busywaitinterval = 20;
-#ifdef WITH_THREAD
#ifndef MS_WINDOWS
/* Millisecond sleep() for Unix platforms. */
PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
return 0;
}
-#endif /* WITH_THREAD */
return 0;
}
#endif
-#ifdef WITH_THREAD
if (v->threaded && tcl_lock) {
/* If Tcl is threaded, we don't need the lock. */
PyThread_free_lock(tcl_lock);
tcl_lock = NULL;
}
-#endif
v->OldBooleanType = Tcl_GetObjType("boolean");
v->BooleanType = Tcl_GetObjType("booleanString");
}
-#ifdef WITH_THREAD
static void
Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev,
Tcl_Condition *cond, Tcl_Mutex *mutex)
Tcl_MutexUnlock(mutex);
Py_END_ALLOW_THREADS
}
-#endif
/** Tcl Eval **/
return newPyTclObject(value);
}
-#ifdef WITH_THREAD
/* This mutex synchronizes inter-thread command calls. */
TCL_DECLARE_MUTEX(call_mutex)
PyObject **exc_type, **exc_value, **exc_tb;
Tcl_Condition *done;
} Tkapp_CallEvent;
-#endif
void
Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc)
return res;
}
-#ifdef WITH_THREAD
/* Tkapp_CallProc is the event procedure that is executed in the context of
the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
return 1;
}
-#endif
/* This is the main entry point for calling a Tcl command.
It supports three cases, with regard to threading:
if (PyTuple_Check(item))
args = item;
}
-#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
/* We cannot call the command directly. Instead, we must
marshal the parameters to the interpreter thread. */
Tcl_ConditionFinalize(&cond);
}
else
-#endif
{
objv = Tkapp_CallArgs(args, objStore, &objc);
typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
-#ifdef WITH_THREAD
TCL_DECLARE_MUTEX(var_mutex)
typedef struct VarEvent {
PyObject **exc_val;
Tcl_Condition *cond;
} VarEvent;
-#endif
/*[python]
return 0;
}
-#ifdef WITH_THREAD
static void
var_perform(VarEvent *ev)
return 1;
}
-#endif
static PyObject*
var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
{
-#ifdef WITH_THREAD
TkappObject *self = (TkappObject*)selfptr;
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
VarEvent *ev;
}
return res;
}
-#endif
/* Tcl is not threaded, or this is the interpreter thread. */
return func(selfptr, args, flags);
}
-#ifdef WITH_THREAD
TCL_DECLARE_MUTEX(command_mutex)
typedef struct CommandEvent{
Tcl_MutexUnlock(&command_mutex);
return 1;
}
-#endif
/*[clinic input]
_tkinter.tkapp.createcommand
return NULL;
}
-#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
!WaitForMainloop(self))
return NULL;
-#endif
data = PyMem_NEW(PythonCmd_ClientData, 1);
if (!data)
Py_INCREF(func);
data->self = (PyObject *) self;
data->func = func;
-#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Tcl_Condition cond = NULL;
CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
Tcl_ConditionFinalize(&cond);
}
else
-#endif
{
ENTER_TCL
err = Tcl_CreateCommand(
CHECK_STRING_LENGTH(name);
-#ifdef WITH_THREAD
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
Tcl_Condition cond = NULL;
CommandEvent *ev;
Tcl_ConditionFinalize(&cond);
}
else
-#endif
{
ENTER_TCL
err = Tcl_DeleteCommand(self->interp, name);
_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold)
/*[clinic end generated code: output=0ba8eabbe57841b0 input=036bcdcf03d5eca0]*/
{
-#ifdef WITH_THREAD
PyThreadState *tstate = PyThreadState_Get();
-#endif
CHECK_TCL_APPARTMENT;
self->dispatching = 1;
{
int result;
-#ifdef WITH_THREAD
if (self->threaded) {
/* Allow other Python threads to run. */
ENTER_TCL
Sleep(Tkinter_busywaitinterval);
Py_END_ALLOW_THREADS
}
-#else
- result = Tcl_DoOneEvent(0);
-#endif
if (PyErr_CheckSignals() != 0) {
self->dispatching = 0;
}
#endif
-#ifdef WITH_THREAD
static PyThreadState *event_tstate = NULL;
-#endif
static int
EventHook(void)
#ifndef MS_WINDOWS
int tfile;
#endif
-#ifdef WITH_THREAD
PyEval_RestoreThread(event_tstate);
-#endif
stdin_ready = 0;
errorInCmd = 0;
#ifndef MS_WINDOWS
break;
}
#endif
-#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Py_BEGIN_ALLOW_THREADS
if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = event_tstate;
if (result == 0)
Sleep(Tkinter_busywaitinterval);
Py_END_ALLOW_THREADS
-#else
- result = Tcl_DoOneEvent(0);
-#endif
if (result < 0)
break;
excInCmd = valInCmd = trbInCmd = NULL;
PyErr_Print();
}
-#ifdef WITH_THREAD
PyEval_SaveThread();
-#endif
return 0;
}
{
#ifdef WAIT_FOR_STDIN
if (PyOS_InputHook == NULL) {
-#ifdef WITH_THREAD
event_tstate = PyThreadState_Get();
-#endif
PyOS_InputHook = EventHook;
}
#endif
{
PyObject *m, *uexe, *cexe, *o;
-#ifdef WITH_THREAD
tcl_lock = PyThread_allocate_lock();
if (tcl_lock == NULL)
return NULL;
-#endif
m = PyModule_Create(&_tkintermodule);
if (m == NULL)
int use_domain;
} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 1, 0};
-#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD)
+#if defined(TRACE_RAW_MALLOC)
/* This lock is needed because tracemalloc_free() is called without
the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
would introduce a deadlock in PyThreadState_DeleteCurrent(). */
#endif
-#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
+#if defined(TRACE_RAW_MALLOC)
#define REENTRANT_THREADLOCAL
/* If your OS does not provide native thread local storage, you can implement
#else
-/* WITH_THREAD not defined: Python compiled without threads,
- or TRACE_RAW_MALLOC not defined: variable protected by the GIL */
+/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */
static int tracemalloc_reentrant = 0;
static int
PyThreadState *tstate;
PyFrameObject *pyframe;
-#ifdef WITH_THREAD
tstate = PyGILState_GetThisThreadState();
-#else
- tstate = PyThreadState_Get();
-#endif
if (tstate == NULL) {
#ifdef TRACE_DEBUG
tracemalloc_error("failed to get the current thread state");
traceback_t *traceback;
_Py_hashtable_entry_t *entry;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
/* get frames */
traceback = tracemalloc_traceback;
static void*
tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
{
-#ifdef WITH_THREAD
PyGILState_STATE gil_state;
-#endif
void *ptr;
if (get_reentrant()) {
disabled. */
set_reentrant(1);
-#ifdef WITH_THREAD
gil_state = PyGILState_Ensure();
ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
PyGILState_Release(gil_state);
-#else
- ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize);
-#endif
set_reentrant(0);
return ptr;
static void*
tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size)
{
-#ifdef WITH_THREAD
PyGILState_STATE gil_state;
-#endif
void *ptr2;
if (get_reentrant()) {
not disabled. */
set_reentrant(1);
-#ifdef WITH_THREAD
gil_state = PyGILState_Ensure();
ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
PyGILState_Release(gil_state);
-#else
- ptr2 = tracemalloc_realloc(ctx, ptr, new_size);
-#endif
set_reentrant(0);
return ptr2;
static void
tracemalloc_clear_traces(void)
{
-#ifdef WITH_THREAD
/* The GIL protects variables againt concurrent access */
assert(PyGILState_Check());
-#endif
TABLES_LOCK();
_Py_hashtable_clear(tracemalloc_traces);
}
#endif
-#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
+#if defined(TRACE_RAW_MALLOC)
if (tables_lock == NULL) {
tables_lock = PyThread_allocate_lock();
if (tables_lock == NULL) {
_Py_hashtable_destroy(tracemalloc_filenames);
_Py_hashtable_destroy(tracemalloc_traces);
-#if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC)
+#if defined(TRACE_RAW_MALLOC)
if (tables_lock != NULL) {
PyThread_free_lock(tables_lock);
tables_lock = NULL;
char *p;
int nframe;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
if ((p = Py_GETENV("PYTHONTRACEMALLOC")) && *p != '\0') {
char *endptr = p;
void
_PyTraceMalloc_Fini(void)
{
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
tracemalloc_deinit();
}
size_t size)
{
int res;
-#ifdef WITH_THREAD
PyGILState_STATE gil_state;
-#endif
if (!tracemalloc_config.tracing) {
/* tracemalloc is not tracing: do nothing */
return -2;
}
-#ifdef WITH_THREAD
gil_state = PyGILState_Ensure();
-#endif
TABLES_LOCK();
res = tracemalloc_add_trace(domain, ptr, size);
TABLES_UNLOCK();
-#ifdef WITH_THREAD
PyGILState_Release(gil_state);
-#endif
return res;
}
#endif /* defined(HAVE_SIGTIMEDWAIT) */
-#if (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD))
+#if defined(HAVE_PTHREAD_KILL)
PyDoc_STRVAR(signal_pthread_kill__doc__,
"pthread_kill($module, thread_id, signalnum, /)\n"
return return_value;
}
-#endif /* (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)) */
+#endif /* defined(HAVE_PTHREAD_KILL) */
#ifndef SIGNAL_ALARM_METHODDEF
#define SIGNAL_ALARM_METHODDEF
#ifndef SIGNAL_PTHREAD_KILL_METHODDEF
#define SIGNAL_PTHREAD_KILL_METHODDEF
#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
-/*[clinic end generated code: output=9403ef0c5d0f7ee0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3f6e6298696f1b75 input=a9049054013a1b77]*/
/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
-#ifdef WITH_THREAD
-# define FAULTHANDLER_LATER
-#endif
+#define FAULTHANDLER_LATER
#ifndef MS_WINDOWS
/* register() is useless on Windows, because only SIGSEGV, SIGABRT and
reentrant = 1;
-#ifdef WITH_THREAD
/* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
are thus delivered to the thread that caused the fault. Get the Python
thread state of the current thread.
used. Read the thread local storage (TLS) instead: call
PyGILState_GetThisThreadState(). */
tstate = PyGILState_GetThisThreadState();
-#else
- tstate = _PyThreadState_UncheckedGet();
-#endif
if (all_threads) {
(void)_Py_DumpTracebackThreads(fd, NULL, tstate);
Py_RETURN_NONE;
}
-#ifdef WITH_THREAD
static void
faulthandler_fatal_error_thread(void *plock)
{
Py_RETURN_NONE;
}
-#endif
static PyObject *
faulthandler_sigfpe(PyObject *self, PyObject *args)
"a SIGSEGV or SIGBUS signal depending on the platform")},
{"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
-#ifdef WITH_THREAD
{"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
PyDoc_STR("fatal_error_c_thread(): "
"call Py_FatalError() in a new C thread.")},
-#endif
{"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
{"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
* an operation.
*/
-#ifdef WITH_THREAD
#include "pythread.h"
- #define ENTER_HASHLIB(obj) \
- if ((obj)->lock) { \
- if (!PyThread_acquire_lock((obj)->lock, 0)) { \
- Py_BEGIN_ALLOW_THREADS \
- PyThread_acquire_lock((obj)->lock, 1); \
- Py_END_ALLOW_THREADS \
- } \
- }
- #define LEAVE_HASHLIB(obj) \
- if ((obj)->lock) { \
- PyThread_release_lock((obj)->lock); \
- }
-#else
- #define ENTER_HASHLIB(obj)
- #define LEAVE_HASHLIB(obj)
-#endif
+#define ENTER_HASHLIB(obj) \
+ if ((obj)->lock) { \
+ if (!PyThread_acquire_lock((obj)->lock, 0)) { \
+ Py_BEGIN_ALLOW_THREADS \
+ PyThread_acquire_lock((obj)->lock, 1); \
+ Py_END_ALLOW_THREADS \
+ } \
+ }
+#define LEAVE_HASHLIB(obj) \
+ if ((obj)->lock) { \
+ PyThread_release_lock((obj)->lock); \
+ }
/* TODO(gps): We should probably make this a module or EVPobject attribute
* to allow the user to optimize based on the platform they're using. */
/* Don't use the "_r" form if we don't need it (also, won't have a
prototype for it, at least on Solaris -- maybe others as well?). */
-#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
+#if defined(HAVE_CTERMID_R)
#define USE_CTERMID_R
#endif
void
PyOS_AfterFork_Child(void)
{
-#ifdef WITH_THREAD
/* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
* can be called safely. */
PyThread_ReInitTLS();
_PyGILState_Reinit();
PyEval_ReInitThreads();
_PyImport_ReInitLock();
-#endif
_PySignal_AfterFork();
run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
#endif
{
int r;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate = PyGILState_Ensure();
-#endif
r = on_hook(readlinestate_global->startup_hook);
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return r;
}
#endif
{
int r;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate = PyGILState_Ensure();
-#endif
r = on_hook(readlinestate_global->pre_input_hook);
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return r;
}
#endif
{
int i;
PyObject *sub, *m=NULL, *s=NULL, *r=NULL;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate = PyGILState_Ensure();
-#endif
m = PyList_New(num_matches);
if (m == NULL)
goto error;
Py_XDECREF(m);
Py_XDECREF(r);
}
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
}
#endif
char *result = NULL;
if (readlinestate_global->completer != NULL) {
PyObject *r = NULL, *t;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate = PyGILState_Ensure();
-#endif
rl_attempted_completion_over = 1;
t = decode(text);
r = PyObject_CallFunction(readlinestate_global->completer, "Ni", t, state);
PyErr_Clear();
Py_XDECREF(r);
done:
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return result;
}
return result;
char saved;
size_t start_size, end_size;
wchar_t *s;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate = PyGILState_Ensure();
-#endif
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
rl_completion_append_character ='\0';
#endif
readlinestate_global->begidx = PyLong_FromLong((long) start);
readlinestate_global->endidx = PyLong_FromLong((long) end);
result = completion_matches((char *)text, *on_completion);
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
return result;
}
}
else if (err == EINTR) {
int s;
-#ifdef WITH_THREAD
PyEval_RestoreThread(_PyOS_ReadlineTState);
-#endif
s = PyErr_CheckSignals();
-#ifdef WITH_THREAD
PyEval_SaveThread();
-#endif
if (s < 0) {
rl_free_line_state();
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700
thread. XXX This is a hack.
*/
-#ifdef WITH_THREAD
#include <sys/types.h> /* For pid_t */
#include "pythread.h"
static unsigned long main_thread;
static pid_t main_pid;
-#endif
static volatile struct {
_Py_atomic_int tripped;
{
int save_errno = errno;
-#ifdef WITH_THREAD
/* See NOTES section above */
if (getpid() == main_pid)
-#endif
{
trip_signal(sig_num);
}
return NULL;
}
#endif
-#ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread) {
PyErr_SetString(PyExc_ValueError,
"signal only works in main thread");
return NULL;
}
-#endif
if (signalnum < 1 || signalnum >= NSIG) {
PyErr_SetString(PyExc_ValueError,
"signal number out of range");
return NULL;
#endif
-#ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread) {
PyErr_SetString(PyExc_ValueError,
"set_wakeup_fd only works in main thread");
return NULL;
}
-#endif
#ifdef MS_WINDOWS
is_socket = 0;
#endif /* #ifdef HAVE_SIGTIMEDWAIT */
-#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
+#if defined(HAVE_PTHREAD_KILL)
/*[clinic input]
signal.pthread_kill
Py_RETURN_NONE;
}
-#endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */
+#endif /* #if defined(HAVE_PTHREAD_KILL) */
PyObject *m, *d, *x;
int i;
-#ifdef WITH_THREAD
main_thread = PyThread_get_thread_ident();
main_pid = getpid();
-#endif
/* Create the module and add the functions */
m = PyModule_Create(&signalmodule);
if (!_Py_atomic_load(&is_tripped))
return 0;
-#ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread)
return 0;
-#endif
/*
* The is_tripped variable is meant to speed up the calls to
PyOS_InterruptOccurred(void)
{
if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
-#ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread)
return 0;
-#endif
_Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
return 1;
}
* in both processes if they came in just before the fork() but before
* the interpreter had an opportunity to call the handlers. issue9535. */
_clear_pending_signals();
-#ifdef WITH_THREAD
main_thread = PyThread_get_thread_ident();
main_pid = getpid();
-#endif
}
int
_PyOS_IsMainThread(void)
{
-#ifdef WITH_THREAD
return PyThread_get_thread_ident() == main_thread;
-#else
- return 1;
-#endif
}
#ifdef MS_WINDOWS
# include <sys/uio.h>
#endif
-#if !defined(WITH_THREAD)
-# undef HAVE_GETHOSTBYNAME_R
-#endif
-
#if defined(__ANDROID__) && __ANDROID_API__ < 23
# undef HAVE_GETHOSTBYNAME_R
#endif
# endif
#endif
-#if !defined(HAVE_GETHOSTBYNAME_R) && defined(WITH_THREAD) && \
- !defined(MS_WINDOWS)
+#if !defined(HAVE_GETHOSTBYNAME_R) && !defined(MS_WINDOWS)
# define USE_GETHOSTBYNAME_LOCK
#endif
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83
*/
-#if defined(WITH_THREAD) && ( \
- (defined(__APPLE__) && \
+#if ((defined(__APPLE__) && \
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \
(defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
(defined(__OpenBSD__) && OpenBSD+0 < 201311) || \
struct timeval tv, *tvp;
#endif
-#ifdef WITH_THREAD
/* must be called with the GIL held */
assert(PyGILState_Check());
-#endif
/* Error condition is for output only */
assert(!(connect && !writing));
int deadline_initialized = 0;
int res;
-#ifdef WITH_THREAD
/* sock_call() must be called with the GIL held. */
assert(PyGILState_Check());
-#endif
/* outer loop to retry select() when select() is interrupted by a signal
or to retry select()+sock_func() on false positive (see above) */
#include "zlib.h"
-#ifdef WITH_THREAD
- #include "pythread.h"
- #define ENTER_ZLIB(obj) \
- Py_BEGIN_ALLOW_THREADS; \
- PyThread_acquire_lock((obj)->lock, 1); \
- Py_END_ALLOW_THREADS;
- #define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock);
-#else
- #define ENTER_ZLIB(obj)
- #define LEAVE_ZLIB(obj)
-#endif
+#include "pythread.h"
+#define ENTER_ZLIB(obj) \
+ Py_BEGIN_ALLOW_THREADS; \
+ PyThread_acquire_lock((obj)->lock, 1); \
+ Py_END_ALLOW_THREADS;
+#define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock);
#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
# define AT_LEAST_ZLIB_1_2_2_1
char eof;
int is_initialised;
PyObject *zdict;
- #ifdef WITH_THREAD
- PyThread_type_lock lock;
- #endif
+ PyThread_type_lock lock;
} compobject;
static void
Py_DECREF(self);
return NULL;
}
-#ifdef WITH_THREAD
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
Py_DECREF(self);
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
return NULL;
}
-#endif
return self;
}
static void
Dealloc(compobject *self)
{
-#ifdef WITH_THREAD
PyThread_free_lock(self->lock);
-#endif
Py_XDECREF(self->unused_data);
Py_XDECREF(self->unconsumed_tail);
Py_XDECREF(self->zdict);
if (op == NULL)
fprintf(stderr, "NULL\n");
else {
-#ifdef WITH_THREAD
PyGILState_STATE gil;
-#endif
PyObject *error_type, *error_value, *error_traceback;
fprintf(stderr, "object : ");
-#ifdef WITH_THREAD
gil = PyGILState_Ensure();
-#endif
PyErr_Fetch(&error_type, &error_value, &error_traceback);
(void)PyObject_Print(op, stderr, 0);
PyErr_Restore(error_type, error_value, error_traceback);
-#ifdef WITH_THREAD
PyGILState_Release(gil);
-#endif
/* XXX(twouters) cast refcount to long until %zd is
universally available */
fprintf(stderr, "\n"
static void
_PyMem_DebugCheckGIL(void)
{
-#ifdef WITH_THREAD
if (!PyGILState_Check())
Py_FatalError("Python memory allocator called "
"without holding the GIL");
-#endif
}
static void *
{"_sha3", PyInit__sha3},
{"_blake2", PyInit__blake2},
{"time", PyInit_time},
-#ifdef WITH_THREAD
{"_thread", PyInit__thread},
-#endif
#ifdef WIN32
{"msvcrt", PyInit_msvcrt},
{"_locale", PyInit__locale},
PyThreadState* _PyOS_ReadlineTState;
-#ifdef WITH_THREAD
#include "pythread.h"
static PyThread_type_lock _PyOS_ReadlineLock = NULL;
-#endif
int (*PyOS_InputHook)(void) = NULL;
#ifdef EINTR
if (err == EINTR) {
int s;
-#ifdef WITH_THREAD
PyEval_RestoreThread(_PyOS_ReadlineTState);
-#endif
s = PyErr_CheckSignals();
-#ifdef WITH_THREAD
PyEval_SaveThread();
-#endif
if (s < 0)
return 1;
/* try again */
if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE)
== WAIT_OBJECT_0) {
ResetEvent(hInterruptEvent);
-#ifdef WITH_THREAD
PyEval_RestoreThread(_PyOS_ReadlineTState);
-#endif
s = PyErr_CheckSignals();
-#ifdef WITH_THREAD
PyEval_SaveThread();
-#endif
if (s < 0)
goto exit;
}
PyMem_RawFree(wbuf);
if (err) {
-#ifdef WITH_THREAD
PyEval_RestoreThread(_PyOS_ReadlineTState);
-#endif
PyErr_SetFromWindowsErr(err);
-#ifdef WITH_THREAD
PyEval_SaveThread();
-#endif
}
return buf;
PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
}
-#ifdef WITH_THREAD
if (_PyOS_ReadlineLock == NULL) {
_PyOS_ReadlineLock = PyThread_allocate_lock();
}
-#endif
_PyOS_ReadlineTState = PyThreadState_GET();
Py_BEGIN_ALLOW_THREADS
-#ifdef WITH_THREAD
PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
-#endif
/* This is needed to handle the unlikely case that the
* interpreter is in interactive mode *and* stdin/out are not
prompt);
Py_END_ALLOW_THREADS
-#ifdef WITH_THREAD
PyThread_release_lock(_PyOS_ReadlineLock);
-#endif
_PyOS_ReadlineTState = NULL;
exit(sts);
}
-#ifdef WITH_THREAD
/* Needed by obmalloc.c */
int PyGILState_Check(void)
{ return 1; }
-#endif
void _PyMem_DumpTraceback(int fd, const void *ptr)
{}
static int test_repeated_init_and_subinterpreters(void)
{
PyThreadState *mainstate, *substate;
-#ifdef WITH_THREAD
PyGILState_STATE gilstate;
-#endif
int i, j;
for (i=0; i<15; i++) {
_testembed_Py_Initialize();
mainstate = PyThreadState_Get();
-#ifdef WITH_THREAD
PyEval_InitThreads();
PyEval_ReleaseThread(mainstate);
gilstate = PyGILState_Ensure();
-#endif
print_subinterp();
PyThreadState_Swap(NULL);
PyThreadState_Swap(mainstate);
print_subinterp();
-#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-#endif
PyEval_RestoreThread(mainstate);
Py_Finalize();
#endif
#endif
-#ifdef WITH_THREAD
#define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
-#else
-#define GIL_REQUEST 0
-#endif
/* This can set eval_breaker to 0 even though gil_drop_request became
1. We believe this is all right because the eval loop will release
_Py_atomic_load_relaxed(&pendingcalls_to_do) | \
pending_async_exc)
-#ifdef WITH_THREAD
-
#define SET_GIL_DROP_REQUEST() \
do { \
_Py_atomic_store_relaxed(&gil_drop_request, 1); \
COMPUTE_EVAL_BREAKER(); \
} while (0)
-#endif
-
/* Pending calls are only modified under pending_lock */
#define SIGNAL_PENDING_CALLS() \
do { \
Guarded by the GIL. */
static int pending_async_exc = 0;
-#ifdef WITH_THREAD
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
_PyThreadState_DeleteExcept(current_tstate);
}
-#endif /* WITH_THREAD */
-
/* This function is used to signal that async exceptions are waiting to be
raised, therefore it is also useful in non-threaded builds. */
PyThreadState *tstate = PyThreadState_Swap(NULL);
if (tstate == NULL)
Py_FatalError("PyEval_SaveThread: NULL tstate");
-#ifdef WITH_THREAD
if (gil_created())
drop_gil(tstate);
-#endif
return tstate;
}
{
if (tstate == NULL)
Py_FatalError("PyEval_RestoreThread: NULL tstate");
-#ifdef WITH_THREAD
if (gil_created()) {
int err = errno;
take_gil(tstate);
}
errno = err;
}
-#endif
PyThreadState_Swap(tstate);
}
Note that because registry may occur from within signal handlers,
or other asynchronous events, calling malloc() is unsafe!
-#ifdef WITH_THREAD
Any thread can schedule pending calls, but only the main thread
will execute them.
There is no facility to schedule calls to a particular thread, but
that should be easy to change, should that ever be required. In
that case, the static variables here should go into the python
threadstate.
-#endif
*/
void
SIGNAL_PENDING_CALLS();
}
-#ifdef WITH_THREAD
-
-/* The WITH_THREAD implementation is thread-safe. It allows
+/* This implementation is thread-safe. It allows
scheduling to be made from any thread, and even from an executing
callback.
*/
return -1;
}
-#else /* if ! defined WITH_THREAD */
-
-/*
- WARNING! ASYNCHRONOUSLY EXECUTING CODE!
- This code is used for signal handling in python that isn't built
- with WITH_THREAD.
- Don't use this implementation when Py_AddPendingCalls() can happen
- on a different thread!
-
- There are two possible race conditions:
- (1) nested asynchronous calls to Py_AddPendingCall()
- (2) AddPendingCall() calls made while pending calls are being processed.
-
- (1) is very unlikely because typically signal delivery
- is blocked during signal handling. So it should be impossible.
- (2) is a real possibility.
- The current code is safe against (2), but not against (1).
- The safety against (2) is derived from the fact that only one
- thread is present, interrupted by signals, and that the critical
- section is protected with the "busy" variable. On Windows, which
- delivers SIGINT on a system thread, this does not hold and therefore
- Windows really shouldn't use this version.
- The two threads could theoretically wiggle around the "busy" variable.
-*/
-
-#define NPENDINGCALLS 32
-static struct {
- int (*func)(void *);
- void *arg;
-} pendingcalls[NPENDINGCALLS];
-static volatile int pendingfirst = 0;
-static volatile int pendinglast = 0;
-
-int
-Py_AddPendingCall(int (*func)(void *), void *arg)
-{
- static volatile int busy = 0;
- int i, j;
- /* XXX Begin critical section */
- if (busy)
- return -1;
- busy = 1;
- i = pendinglast;
- j = (i + 1) % NPENDINGCALLS;
- if (j == pendingfirst) {
- busy = 0;
- return -1; /* Queue full */
- }
- pendingcalls[i].func = func;
- pendingcalls[i].arg = arg;
- pendinglast = j;
-
- SIGNAL_PENDING_CALLS();
- busy = 0;
- /* XXX End critical section */
- return 0;
-}
-
-int
-Py_MakePendingCalls(void)
-{
- static int busy = 0;
- if (busy)
- return 0;
- busy = 1;
-
- /* unsignal before starting to call callbacks, so that any callback
- added in-between re-signals */
- UNSIGNAL_PENDING_CALLS();
- /* Python signal handler doesn't really queue a callback: it only signals
- that a signal was received, see _PyEval_SignalReceived(). */
- if (PyErr_CheckSignals() < 0) {
- goto error;
- }
-
- for (;;) {
- int i;
- int (*func)(void *);
- void *arg;
- i = pendingfirst;
- if (i == pendinglast)
- break; /* Queue empty */
- func = pendingcalls[i].func;
- arg = pendingcalls[i].arg;
- pendingfirst = (i + 1) % NPENDINGCALLS;
- if (func(arg) < 0) {
- goto error;
- }
- }
- busy = 0;
- return 0;
-
-error:
- busy = 0;
- SIGNAL_PENDING_CALLS(); /* We're not done yet */
- return -1;
-}
-
-#endif /* WITH_THREAD */
-
/* The interpreter's recursion limit */
if (Py_MakePendingCalls() < 0)
goto error;
}
-#ifdef WITH_THREAD
if (_Py_atomic_load_relaxed(&gil_drop_request)) {
/* Give another thread a chance */
if (PyThreadState_Swap(NULL) != tstate)
if (PyThreadState_Swap(tstate) != NULL)
Py_FatalError("ceval: orphan tstate");
}
-#endif
/* Check for asynchronous exceptions. */
if (tstate->async_exc != NULL) {
PyObject *exc = tstate->async_exc;
{
int res;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
Py_BEGIN_ALLOW_THREADS
res = _Py_fstat_noraise(fd, status);
int
_Py_open(const char *pathname, int flags)
{
-#ifdef WITH_THREAD
/* _Py_open() must be called with the GIL held. */
assert(PyGILState_Check());
-#endif
return _Py_open_impl(pathname, flags, 1);
}
wchar_t wmode[10];
int usize;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
if (!PyUnicode_Check(path)) {
PyErr_Format(PyExc_TypeError,
PyObject *bytes;
char *path_bytes;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
if (!PyUnicode_FSConverter(path, &bytes))
return NULL;
int err;
int async_err = 0;
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
/* _Py_read() must not be called with an exception set, otherwise the
* caller may think that read() was interrupted by a signal and the signal
Py_ssize_t
_Py_write(int fd, const void *buf, size_t count)
{
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
/* _Py_write() must not be called with an exception set, otherwise the
* caller may think that write() was interrupted by a signal and the signal
DWORD ftype;
#endif
-#ifdef WITH_THREAD
assert(PyGILState_Check());
-#endif
#ifdef MS_WINDOWS
_Py_BEGIN_SUPPRESS_IPH
in different threads to return with a partially loaded module.
These calls are serialized by the global interpreter lock. */
-#ifdef WITH_THREAD
-
#include "pythread.h"
static PyThread_type_lock import_lock = 0;
}
}
-#endif
-
/*[clinic input]
_imp.lock_held
_imp_lock_held_impl(PyObject *module)
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
{
-#ifdef WITH_THREAD
return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID);
-#else
- Py_RETURN_FALSE;
-#endif
}
/*[clinic input]
_imp_acquire_lock_impl(PyObject *module)
/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/
{
-#ifdef WITH_THREAD
_PyImport_AcquireLock();
-#endif
Py_RETURN_NONE;
}
_imp_release_lock_impl(PyObject *module)
/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/
{
-#ifdef WITH_THREAD
if (_PyImport_ReleaseLock() < 0) {
PyErr_SetString(PyExc_RuntimeError,
"not holding the import lock");
return NULL;
}
-#endif
Py_RETURN_NONE;
}
_PyImport_Fini(void)
{
Py_CLEAR(extensions);
-#ifdef WITH_THREAD
if (import_lock != NULL) {
PyThread_free_lock(import_lock);
import_lock = NULL;
}
-#endif
}
/* Helper for sys */
#include "Python.h"
-#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
+#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
#define _SGI_MP_SOURCE
#endif
extern int _PyTraceMalloc_Fini(void);
extern void _Py_ReadyTypes(void);
-#ifdef WITH_THREAD
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
extern void _PyGILState_Fini(void);
-#endif /* WITH_THREAD */
/* Global configuration variable declarations are in pydebug.h */
/* XXX (ncoghlan): move those declarations to pylifecycle.h? */
Py_FatalError("Py_InitializeCore: can't make first thread");
(void) PyThreadState_Swap(tstate);
-#ifdef WITH_THREAD
/* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because
destroying the GIL might fail when it is being referenced from
another running thread (see issue #9901).
_PyEval_FiniThreads();
/* Auto-thread-state API */
_PyGILState_Init(interp, tstate);
-#endif /* WITH_THREAD */
_Py_ReadyTypes();
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
/* Cleanup auto-thread-state */
-#ifdef WITH_THREAD
_PyGILState_Fini();
-#endif /* WITH_THREAD */
/* Delete current thread. After this, many C API calls become crashy. */
PyThreadState_Swap(NULL);
if (!_Py_Initialized)
Py_FatalError("Py_NewInterpreter: call Py_Initialize first");
-#ifdef WITH_THREAD
/* Issue #10915, #15751: The GIL API doesn't work with multiple
interpreters: disable PyGILState_Check(). */
_PyGILState_check_enabled = 0;
-#endif
interp = PyInterpreterState_New();
if (interp == NULL)
/* Clean up and exit */
-#ifdef WITH_THREAD
# include "pythread.h"
-#endif
static void (*pyexitfunc)(void) = NULL;
/* For the atexit module. */
static void
wait_for_thread_shutdown(void)
{
-#ifdef WITH_THREAD
_Py_IDENTIFIER(_shutdown);
PyObject *result;
PyObject *threading = _PyImport_GetModuleId(&PyId_threading);
Py_DECREF(result);
}
Py_DECREF(threading);
-#endif
}
#define NEXITFUNCS 32
int _PyGILState_check_enabled = 1;
-#ifdef WITH_THREAD
#include "pythread.h"
static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
/* TODO: Given interp_main, it may be possible to kill this ref */
static PyInterpreterState *autoInterpreterState = NULL;
static int autoTLSkey = -1;
-#else
-#define HEAD_INIT() /* Nothing */
-#define HEAD_LOCK() /* Nothing */
-#define HEAD_UNLOCK() /* Nothing */
-#endif
static PyInterpreterState *interp_head = NULL;
static PyInterpreterState *interp_main = NULL;
_Py_atomic_address _PyThreadState_Current = {0};
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
-#ifdef WITH_THREAD
static void _PyGILState_NoteThreadState(PyThreadState* tstate);
-#endif
/* _next_interp_id is an auto-numbered sequence of small integers.
It gets initialized in _PyInterpreterState_Init(), which is called
if (interp != NULL) {
HEAD_INIT();
-#ifdef WITH_THREAD
if (head_mutex == NULL)
Py_FatalError("Can't initialize threads for interpreter");
-#endif
interp->modules_by_index = NULL;
interp->sysdict = NULL;
interp->builtins = NULL;
}
HEAD_UNLOCK();
PyMem_RawFree(interp);
-#ifdef WITH_THREAD
if (interp_head == NULL && head_mutex != NULL) {
PyThread_free_lock(head_mutex);
head_mutex = NULL;
}
-#endif
}
tstate->use_tracing = 0;
tstate->gilstate_counter = 0;
tstate->async_exc = NULL;
-#ifdef WITH_THREAD
tstate->thread_id = PyThread_get_thread_ident();
-#else
- tstate->thread_id = 0;
-#endif
tstate->dict = NULL;
void
_PyThreadState_Init(PyThreadState *tstate)
{
-#ifdef WITH_THREAD
_PyGILState_NoteThreadState(tstate);
-#endif
}
PyObject*
{
if (tstate == GET_TSTATE())
Py_FatalError("PyThreadState_Delete: tstate is still current");
-#ifdef WITH_THREAD
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
-#endif /* WITH_THREAD */
tstate_delete_common(tstate);
}
-#ifdef WITH_THREAD
void
PyThreadState_DeleteCurrent()
{
SET_TSTATE(NULL);
PyEval_ReleaseLock();
}
-#endif /* WITH_THREAD */
/*
to be used for a thread. Check this the best we can in debug
builds.
*/
-#if defined(Py_DEBUG) && defined(WITH_THREAD)
+#if defined(Py_DEBUG)
if (newts) {
/* This can be called from PyEval_RestoreThread(). Similar
to it, we need to ensure errno doesn't change.
}
/* Python "auto thread state" API. */
-#ifdef WITH_THREAD
/* Keep this as a static, as it is not reliable! It can only
ever be compared to the state for the *current* thread.
void
_PyGILState_Reinit(void)
{
-#ifdef WITH_THREAD
head_mutex = NULL;
HEAD_INIT();
-#endif
PyThreadState *tstate = PyGILState_GetThisThreadState();
PyThread_delete_key(autoTLSkey);
if ((autoTLSkey = PyThread_create_key()) == -1)
PyEval_SaveThread();
}
-#endif /* WITH_THREAD */
#ifdef __cplusplus
}
#endif
-
-
"getcheckinterval() -> current check interval; see setcheckinterval()."
);
-#ifdef WITH_THREAD
static PyObject *
sys_setswitchinterval(PyObject *self, PyObject *args)
{
"getswitchinterval() -> current thread switch interval; see setswitchinterval()."
);
-#endif /* WITH_THREAD */
-
static PyObject *
sys_setrecursionlimit(PyObject *self, PyObject *args)
{
setcheckinterval_doc},
{"getcheckinterval", sys_getcheckinterval, METH_NOARGS,
getcheckinterval_doc},
-#ifdef WITH_THREAD
{"setswitchinterval", sys_setswitchinterval, METH_VARARGS,
setswitchinterval_doc},
{"getswitchinterval", sys_getswitchinterval, METH_NOARGS,
getswitchinterval_doc},
-#endif
#ifdef HAVE_DLOPEN
{"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
setdlopenflags_doc},
PyUnicode_FromString("legacy"));
#endif
-#ifdef WITH_THREAD
SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
-#endif
/* initialize asyncgen_hooks */
if (AsyncGenHooksType.tp_name == NULL) {
PyThreadState *tstate;
unsigned int nthreads;
-#ifdef WITH_THREAD
if (current_tstate == NULL) {
/* _Py_DumpTracebackThreads() is called from signal handlers by
faulthandler.
interp = current_tstate->interp;
}
}
-#else
- if (current_tstate == NULL) {
- /* Call _PyThreadState_UncheckedGet() instead of PyThreadState_Get()
- to not fail with a fatal error if the thread state is NULL. */
- current_tstate = _PyThreadState_UncheckedGet();
- }
-
- if (interp == NULL) {
- if (current_tstate == NULL) {
- /* We need the interpreter state to get Python threads */
- return "unable to get the interpreter state";
- }
- interp = current_tstate->interp;
- }
-#endif
assert(interp != NULL);
/* Get the current interpreter from the current thread */
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-# serial 11 (pkg-config-0.29.1)
-
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29.1)
+dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR
-dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
-dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
-dnl [DESCRIPTION], [DEFAULT])
-dnl ------------------------------------------
-dnl
-dnl Prepare a "--with-" configure option using the lowercase
-dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
-dnl PKG_CHECK_MODULES in a single macro.
-AC_DEFUN([PKG_WITH_MODULES],
-[
-m4_pushdef([with_arg], m4_tolower([$1]))
-
-m4_pushdef([description],
- [m4_default([$5], [build with ]with_arg[ support])])
-
-m4_pushdef([def_arg], [m4_default([$6], [auto])])
-m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
-m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
-
-m4_case(def_arg,
- [yes],[m4_pushdef([with_without], [--without-]with_arg)],
- [m4_pushdef([with_without],[--with-]with_arg)])
-
-AC_ARG_WITH(with_arg,
- AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
- [AS_TR_SH([with_]with_arg)=def_arg])
-
-AS_CASE([$AS_TR_SH([with_]with_arg)],
- [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
- [auto],[PKG_CHECK_MODULES([$1],[$2],
- [m4_n([def_action_if_found]) $3],
- [m4_n([def_action_if_not_found]) $4])])
-
-m4_popdef([with_arg])
-m4_popdef([description])
-m4_popdef([def_arg])
-
-])dnl PKG_WITH_MODULES
-
-dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
-dnl [DESCRIPTION], [DEFAULT])
-dnl -----------------------------------------------
-dnl
-dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
-dnl check._[VARIABLE-PREFIX] is exported as make variable.
-AC_DEFUN([PKG_HAVE_WITH_MODULES],
-[
-PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
-
-AM_CONDITIONAL([HAVE_][$1],
- [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
-])dnl PKG_HAVE_WITH_MODULES
-
-dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
-dnl [DESCRIPTION], [DEFAULT])
-dnl ------------------------------------------------------
-dnl
-dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
-dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
-dnl and preprocessor variable.
-AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
-[
-PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
-
-AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
- [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
-])dnl PKG_HAVE_DEFINE_WITH_MODULES
-
DTRACE_HEADERS
DFLAGS
DTRACE
-THREADOBJ
LDLAST
-USE_THREAD_MODULE
TCLTK_LIBS
TCLTK_INCLUDES
LIBFFI_INCLUDEDIR
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
with_tcltk_includes
with_tcltk_libs
with_dbmliborder
-with_threads
-with_thread
enable_ipv6
with_doc_strings
with_pymalloc
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
order to check db backends for dbm. Valid value is a
colon separated string with the backend names
`ndbm', `gdbm' and `bdb'.
- --with(out)-threads[=DIRECTORY]
- disable/enable thread support
- --with(out)-thread[=DIRECTORY]
- deprecated; use --with(out)-threads
--with(out)-doc-strings disable/enable documentation strings
--with(out)-pymalloc disable/enable specialized mallocs
--with(out)-c-locale-coercion
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dbmliborder" >&5
$as_echo "$with_dbmliborder" >&6; }
-# This is used to generate Setup.config
-
-USE_THREAD_MODULE=""
-
# Templates for things AC_DEFINEd more than once.
# For a single AC_DEFINE, no template is needed.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-threads" >&5
-$as_echo_n "checking for --with-threads... " >&6; }
-
-# Check whether --with-threads was given.
-if test "${with_threads+set}" = set; then :
- withval=$with_threads;
-fi
-
-
-# --with-thread is deprecated, but check for it anyway
-
-# Check whether --with-thread was given.
-if test "${with_thread+set}" = set; then :
- withval=$with_thread; with_threads=$with_thread
-fi
-
-
-if test -z "$with_threads"
-then with_threads="yes"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_threads" >&5
-$as_echo "$with_threads" >&6; }
-
-
-if test "$with_threads" = "no"
+if test "$ac_cv_pthread_is_default" = yes
then
- USE_THREAD_MODULE="#"
-elif test "$ac_cv_pthread_is_default" = yes
-then
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
-
# Defining _REENTRANT on system with POSIX threads should not hurt.
$as_echo "#define _REENTRANT 1" >>confdefs.h
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_kpthread" = "yes"
then
CC="$CC -Kpthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -Kpthread"
fi
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
-
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_kthread" = "yes"
then
CC="$CC -Kthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -Kthread"
fi
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
-
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_pthread" = "yes"
then
CC="$CC -pthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -pthread"
fi
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
-
posix_threads=yes
- THREADOBJ="Python/thread.o"
else
if test ! -z "$with_threads" -a -d "$with_threads"
then LDFLAGS="$LDFLAGS -L$with_threads"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
-
posix_threads=yes
- THREADOBJ="Python/thread.o"
+
else
LIBS=$_libs
ac_fn_c_check_func "$LINENO" "pthread_detach" "ac_cv_func_pthread_detach"
if test "x$ac_cv_func_pthread_detach" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
posix_threads=yes
- THREADOBJ="Python/thread.o"
+
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5
$as_echo "$ac_cv_lib_pthreads_pthread_create" >&6; }
if test "x$ac_cv_lib_pthreads_pthread_create" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
posix_threads=yes
LIBS="$LIBS -lpthreads"
- THREADOBJ="Python/thread.o"
+
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5
$as_echo "$ac_cv_lib_c_r_pthread_create" >&6; }
if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
posix_threads=yes
LIBS="$LIBS -lc_r"
- THREADOBJ="Python/thread.o"
+
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_create_system in -lpthread" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_create_system" >&5
$as_echo "$ac_cv_lib_pthread___pthread_create_system" >&6; }
if test "x$ac_cv_lib_pthread___pthread_create_system" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
posix_threads=yes
LIBS="$LIBS -lpthread"
- THREADOBJ="Python/thread.o"
+
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lcma" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cma_pthread_create" >&5
$as_echo "$ac_cv_lib_cma_pthread_create" >&6; }
if test "x$ac_cv_lib_cma_pthread_create" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
posix_threads=yes
LIBS="$LIBS -lcma"
- THREADOBJ="Python/thread.o"
+
else
- USE_THREAD_MODULE="#"
+ as_fn_error $? "could not find pthreads on your system" "$LINENO" 5
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpc_usconfig" >&5
$as_echo "$ac_cv_lib_mpc_usconfig" >&6; }
if test "x$ac_cv_lib_mpc_usconfig" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
LIBS="$LIBS -lmpc"
- THREADOBJ="Python/thread.o"
- USE_THREAD_MODULE=""
-fi
-
- if test "$posix_threads" != "yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for thr_create in -lthread" >&5
-$as_echo_n "checking for thr_create in -lthread... " >&6; }
-if ${ac_cv_lib_thread_thr_create+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lthread $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char thr_create ();
-int
-main ()
-{
-return thr_create ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_thread_thr_create=yes
-else
- ac_cv_lib_thread_thr_create=no
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_thread_thr_create" >&5
-$as_echo "$ac_cv_lib_thread_thr_create" >&6; }
-if test "x$ac_cv_lib_thread_thr_create" = xyes; then :
- $as_echo "#define WITH_THREAD 1" >>confdefs.h
- LIBS="$LIBS -lthread"
- THREADOBJ="Python/thread.o"
- USE_THREAD_MODULE=""
-fi
- fi
fi
if test "$posix_threads" = "yes"; then
fi
# generate output files
-ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
+ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-config.sh"
ac_config_files="$ac_config_files Modules/ld_so_aix"
"Mac/Resources/framework/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/framework/Info.plist" ;;
"Mac/Resources/app/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/app/Info.plist" ;;
"Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;;
- "Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
"Misc/python-config.sh") CONFIG_FILES="$CONFIG_FILES Misc/python-config.sh" ;;
"Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;;
echo "creating Makefile" >&6
$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
- -s Modules Modules/Setup.config \
+ -s Modules \
Modules/Setup.local Modules/Setup
mv config.c Modules
fi])
AC_MSG_RESULT($with_dbmliborder)
-# This is used to generate Setup.config
-AC_SUBST(USE_THREAD_MODULE)
-USE_THREAD_MODULE=""
-
AC_SUBST(LDLAST)
# Templates for things AC_DEFINEd more than once.
# For a single AC_DEFINE, no template is needed.
AH_TEMPLATE(_REENTRANT,
[Define to force use of thread-safe errno, h_errno, and other functions])
-AH_TEMPLATE(WITH_THREAD,
- [Define if you want to compile in rudimentary thread support])
-
-AC_MSG_CHECKING(for --with-threads)
-dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
-AC_ARG_WITH(threads,
- AS_HELP_STRING([--with(out)-threads@<:@=DIRECTORY@:>@], [disable/enable thread support]))
-
-# --with-thread is deprecated, but check for it anyway
-dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
-AC_ARG_WITH(thread,
- AS_HELP_STRING([--with(out)-thread@<:@=DIRECTORY@:>@], [deprecated; use --with(out)-threads]),
- [with_threads=$with_thread])
-
-if test -z "$with_threads"
-then with_threads="yes"
-fi
-AC_MSG_RESULT($with_threads)
-AC_SUBST(THREADOBJ)
-if test "$with_threads" = "no"
-then
- USE_THREAD_MODULE="#"
-elif test "$ac_cv_pthread_is_default" = yes
+if test "$ac_cv_pthread_is_default" = yes
then
- AC_DEFINE(WITH_THREAD)
# Defining _REENTRANT on system with POSIX threads should not hurt.
AC_DEFINE(_REENTRANT)
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_kpthread" = "yes"
then
CC="$CC -Kpthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -Kpthread"
fi
- AC_DEFINE(WITH_THREAD)
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_kthread" = "yes"
then
CC="$CC -Kthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -Kthread"
fi
- AC_DEFINE(WITH_THREAD)
posix_threads=yes
- THREADOBJ="Python/thread.o"
elif test "$ac_cv_pthread" = "yes"
then
CC="$CC -pthread"
if test "$ac_cv_cxx_thread" = "yes"; then
CXX="$CXX -pthread"
fi
- AC_DEFINE(WITH_THREAD)
posix_threads=yes
- THREADOBJ="Python/thread.o"
else
if test ! -z "$with_threads" -a -d "$with_threads"
then LDFLAGS="$LDFLAGS -L$with_threads"
void * start_routine (void *arg) { exit (0); }]], [[
pthread_create (NULL, NULL, start_routine, NULL)]])],[
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_THREAD)
posix_threads=yes
- THREADOBJ="Python/thread.o"],[
+ ],[
LIBS=$_libs
- AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD)
+ AC_CHECK_FUNC(pthread_detach, [
posix_threads=yes
- THREADOBJ="Python/thread.o"],[
- AC_CHECK_LIB(pthreads, pthread_create, [AC_DEFINE(WITH_THREAD)
+ ],[
+ AC_CHECK_LIB(pthreads, pthread_create, [
posix_threads=yes
LIBS="$LIBS -lpthreads"
- THREADOBJ="Python/thread.o"], [
- AC_CHECK_LIB(c_r, pthread_create, [AC_DEFINE(WITH_THREAD)
+ ], [
+ AC_CHECK_LIB(c_r, pthread_create, [
posix_threads=yes
LIBS="$LIBS -lc_r"
- THREADOBJ="Python/thread.o"], [
- AC_CHECK_LIB(pthread, __pthread_create_system, [AC_DEFINE(WITH_THREAD)
+ ], [
+ AC_CHECK_LIB(pthread, __pthread_create_system, [
posix_threads=yes
LIBS="$LIBS -lpthread"
- THREADOBJ="Python/thread.o"], [
- AC_CHECK_LIB(cma, pthread_create, [AC_DEFINE(WITH_THREAD)
+ ], [
+ AC_CHECK_LIB(cma, pthread_create, [
posix_threads=yes
LIBS="$LIBS -lcma"
- THREADOBJ="Python/thread.o"],[
- USE_THREAD_MODULE="#"])
+ ],[
+ AC_MSG_ERROR([could not find pthreads on your system])
+ ])
])])])])])
- AC_CHECK_LIB(mpc, usconfig, [AC_DEFINE(WITH_THREAD)
+ AC_CHECK_LIB(mpc, usconfig, [
LIBS="$LIBS -lmpc"
- THREADOBJ="Python/thread.o"
- USE_THREAD_MODULE=""])
-
- if test "$posix_threads" != "yes"; then
- AC_CHECK_LIB(thread, thr_create, [AC_DEFINE(WITH_THREAD)
- LIBS="$LIBS -lthread"
- THREADOBJ="Python/thread.o"
- USE_THREAD_MODULE=""])
- fi
+ ])
+
fi
if test "$posix_threads" = "yes"; then
fi
# generate output files
-AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
+AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-config.sh)
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
AC_OUTPUT
echo "creating Makefile" >&AS_MESSAGE_FD
$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
- -s Modules Modules/Setup.config \
+ -s Modules \
Modules/Setup.local Modules/Setup
mv config.c Modules
/* Define if you want to compile in Python-specific mallocs */
#undef WITH_PYMALLOC
-/* Define if you want to compile in rudimentary thread support */
-#undef WITH_THREAD
-
/* Define if you want pymalloc to be disabled when running under valgrind */
#undef WITH_VALGRIND
sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')):
multiprocessing_srcs.append('_multiprocessing/semaphore.c')
- if sysconfig.get_config_var('WITH_THREAD'):
- exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
- define_macros=list(macros.items()),
- include_dirs=["Modules/_multiprocessing"]))
- else:
- missing.append('_multiprocessing')
+ exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
+ define_macros=list(macros.items()),
+ include_dirs=["Modules/_multiprocessing"]))
# End multiprocessing
# Platform-specific libraries
# http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html
undef_macros.append('_FORTIFY_SOURCE')
- # Faster version without thread local contexts:
- if not sysconfig.get_config_var('WITH_THREAD'):
- define_macros.append(('WITHOUT_THREADS', 1))
-
# Uncomment for extra functionality:
#define_macros.append(('EXTRA_FUNCTIONALITY', 1))
ext = Extension (