1"""Faux ``threading`` version using ``dummy_thread`` instead of ``thread``.
2
3The module ``_dummy_threading`` is added to ``sys.modules`` in order
4to not have ``threading`` considered imported.  Had ``threading`` been
5directly imported it would have made all subsequent imports succeed
6regardless of whether ``_thread`` was available which is not desired.
7
8"""
9from sys import modules as sys_modules
10
11import _dummy_thread
12
13# Declaring now so as to not have to nest ``try``s to get proper clean-up.
14holding_thread = False
15holding_threading = False
16holding__threading_local = False
17
18try:
19    # Could have checked if ``_thread`` was not in sys.modules and gone
20    # a different route, but decided to mirror technique used with
21    # ``threading`` below.
22    if '_thread' in sys_modules:
23        held_thread = sys_modules['_thread']
24        holding_thread = True
25    # Must have some module named ``_thread`` that implements its API
26    # in order to initially import ``threading``.
27    sys_modules['_thread'] = sys_modules['_dummy_thread']
28
29    if 'threading' in sys_modules:
30        # If ``threading`` is already imported, might as well prevent
31        # trying to import it more than needed by saving it if it is
32        # already imported before deleting it.
33        held_threading = sys_modules['threading']
34        holding_threading = True
35        del sys_modules['threading']
36
37    if '_threading_local' in sys_modules:
38        # If ``_threading_local`` is already imported, might as well prevent
39        # trying to import it more than needed by saving it if it is
40        # already imported before deleting it.
41        held__threading_local = sys_modules['_threading_local']
42        holding__threading_local = True
43        del sys_modules['_threading_local']
44
45    import threading
46    # Need a copy of the code kept somewhere...
47    sys_modules['_dummy_threading'] = sys_modules['threading']
48    del sys_modules['threading']
49    sys_modules['_dummy__threading_local'] = sys_modules['_threading_local']
50    del sys_modules['_threading_local']
51    from _dummy_threading import *
52    from _dummy_threading import __all__
53
54finally:
55    # Put back ``threading`` if we overwrote earlier
56
57    if holding_threading:
58        sys_modules['threading'] = held_threading
59        del held_threading
60    del holding_threading
61
62    # Put back ``_threading_local`` if we overwrote earlier
63
64    if holding__threading_local:
65        sys_modules['_threading_local'] = held__threading_local
66        del held__threading_local
67    del holding__threading_local
68
69    # Put back ``thread`` if we overwrote, else del the entry we made
70    if holding_thread:
71        sys_modules['_thread'] = held_thread
72        del held_thread
73    else:
74        del sys_modules['_thread']
75    del holding_thread
76
77    del _dummy_thread
78    del sys_modules
79