1
+ {
2
+ "metadata" : {
3
+ "language_info" : {
4
+ "codemirror_mode" : {
5
+ "name" : " ipython" ,
6
+ "version" : 3
7
+ },
8
+ "file_extension" : " .py" ,
9
+ "mimetype" : " text/x-python" ,
10
+ "name" : " python" ,
11
+ "nbconvert_exporter" : " python" ,
12
+ "pygments_lexer" : " ipython3" ,
13
+ "version" : " 3.7.8-final"
14
+ },
15
+ "orig_nbformat" : 2 ,
16
+ "kernelspec" : {
17
+ "name" : " python3" ,
18
+ "display_name" : " Python 3" ,
19
+ "language" : " python"
20
+ }
21
+ },
22
+ "nbformat" : 4 ,
23
+ "nbformat_minor" : 2 ,
24
+ "cells" : [
25
+ {
26
+ "source" : [
27
+ " ### `None` in sys.modules"
28
+ ],
29
+ "cell_type" : " markdown" ,
30
+ "metadata" : {}
31
+ },
32
+ {
33
+ "cell_type" : " code" ,
34
+ "execution_count" : 1 ,
35
+ "metadata" : {},
36
+ "outputs" : [
37
+ {
38
+ "output_type" : " error" ,
39
+ "ename" : " ModuleNotFoundError" ,
40
+ "evalue" : " import of module halted; None in sys.modules" ,
41
+ "traceback" : [
42
+ " \u001b [0;31m---------------------------------------------------------------------------\u001b [0m" ,
43
+ " \u001b [0;31mModuleNotFoundError\u001b [0m Traceback (most recent call last)" ,
44
+ " \u001b [0;32m<ipython-input-1-20156aa94da0>\u001b [0m in \u001b [0;36m<module>\u001b [0;34m\u001b [0m\n \u001b [1;32m 2\u001b [0m \u001b [0msys\u001b [0m\u001b [0;34m.\u001b [0m\u001b [0mmodules\u001b [0m\u001b [0;34m[\u001b [0m\u001b [0;34m'module'\u001b [0m\u001b [0;34m]\u001b [0m \u001b [0;34m=\u001b [0m \u001b [0;32mNone\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [1;32m 3\u001b [0m \u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0;32m----> 4\u001b [0;31m \u001b [0;32mimport\u001b [0m \u001b [0mmodule\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0m" ,
45
+ " \u001b [0;31mModuleNotFoundError\u001b [0m: import of module halted; None in sys.modules"
46
+ ]
47
+ }
48
+ ],
49
+ "source" : [
50
+ " import sys\n " ,
51
+ " sys.modules['module'] = None\n " ,
52
+ " \n " ,
53
+ " import module"
54
+ ]
55
+ },
56
+ {
57
+ "source" : [
58
+ " ### `sys.meta_path` exhausted"
59
+ ],
60
+ "cell_type" : " markdown" ,
61
+ "metadata" : {}
62
+ },
63
+ {
64
+ "source" : [
65
+ " del sys.modules['module']\n " ,
66
+ " del sys.meta_path[:]\n " ,
67
+ " \n " ,
68
+ " import module"
69
+ ],
70
+ "cell_type" : " code" ,
71
+ "metadata" : {},
72
+ "execution_count" : 2 ,
73
+ "outputs" : [
74
+ {
75
+ "output_type" : " error" ,
76
+ "ename" : " ModuleNotFoundError" ,
77
+ "evalue" : " No module named 'module'" ,
78
+ "traceback" : [
79
+ " \u001b [0;31m---------------------------------------------------------------------------\u001b [0m" ,
80
+ " \u001b [0;31mModuleNotFoundError\u001b [0m Traceback (most recent call last)" ,
81
+ " \u001b [0;32m<ipython-input-2-fd1bf8284402>\u001b [0m in \u001b [0;36m<module>\u001b [0;34m\u001b [0m\n \u001b [1;32m 2\u001b [0m \u001b [0;32mdel\u001b [0m \u001b [0msys\u001b [0m\u001b [0;34m.\u001b [0m\u001b [0mmeta_path\u001b [0m\u001b [0;34m[\u001b [0m\u001b [0;34m:\u001b [0m\u001b [0;34m]\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [1;32m 3\u001b [0m \u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0;32m----> 4\u001b [0;31m \u001b [0;32mimport\u001b [0m \u001b [0mmodule\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0m" ,
82
+ " \u001b [0;31mModuleNotFoundError\u001b [0m: No module named 'module'"
83
+ ]
84
+ }
85
+ ]
86
+ },
87
+ {
88
+ "source" : [
89
+ " ### Spec's loader is `None`"
90
+ ],
91
+ "cell_type" : " markdown" ,
92
+ "metadata" : {}
93
+ },
94
+ {
95
+ "cell_type" : " code" ,
96
+ "execution_count" : 7 ,
97
+ "metadata" : {},
98
+ "outputs" : [
99
+ {
100
+ "output_type" : " error" ,
101
+ "ename" : " ImportError" ,
102
+ "evalue" : " missing loader" ,
103
+ "traceback" : [
104
+ " \u001b [0;31m---------------------------------------------------------------------------\u001b [0m" ,
105
+ " \u001b [0;31mImportError\u001b [0m Traceback (most recent call last)" ,
106
+ " \u001b [0;32m<ipython-input-7-85f7fa80cfc0>\u001b [0m in \u001b [0;36m<module>\u001b [0;34m\u001b [0m\n \u001b [1;32m 9\u001b [0m \u001b [0msys\u001b [0m\u001b [0;34m.\u001b [0m\u001b [0mmeta_path\u001b [0m \u001b [0;34m=\u001b [0m \u001b [0;34m[\u001b [0m\u001b [0mfinder\u001b [0m\u001b [0;34m]\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [1;32m 10\u001b [0m \u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0;32m---> 11\u001b [0;31m \u001b [0;32mimport\u001b [0m \u001b [0mmodule\u001b [0m\u001b [0;34m\u001b [0m\u001b [0;34m\u001b [0m\u001b [0m\n \u001b [0m" ,
107
+ " \u001b [0;31mImportError\u001b [0m: missing loader"
108
+ ]
109
+ }
110
+ ],
111
+ "source" : [
112
+ " from importlib.abc import MetaPathFinder\n " ,
113
+ " from importlib.machinery import ModuleSpec\n " ,
114
+ " \n " ,
115
+ " class NoLoaderFinder(MetaPathFinder):\n " ,
116
+ " def find_spec(self, fullname, path, target=None):\n " ,
117
+ " return ModuleSpec('module', None)\n " ,
118
+ " \n " ,
119
+ " finder = NoLoaderFinder()\n " ,
120
+ " sys.meta_path = [finder]\n " ,
121
+ " \n " ,
122
+ " import module"
123
+ ]
124
+ },
125
+ {
126
+ "source" : [
127
+ " ### Regular loader"
128
+ ],
129
+ "cell_type" : " markdown" ,
130
+ "metadata" : {}
131
+ },
132
+ {
133
+ "cell_type" : " code" ,
134
+ "execution_count" : 17 ,
135
+ "metadata" : {},
136
+ "outputs" : [
137
+ {
138
+ "output_type" : " stream" ,
139
+ "name" : " stdout" ,
140
+ "text" : [
141
+ " module <module 'module' (<__main__.ExampleLoader object at 0x7f782ed6e3d0>)>\n module.name module\n module.x 1\n module.y 2\n ----------\n module2 is module? False\n module2 <module 'module' (<__main__.ExampleLoader object at 0x7f782deab5d0>)>\n module2.name module\n module2.x 1\n module2.y 2\n "
142
+ ]
143
+ }
144
+ ],
145
+ "source" : [
146
+ " from types import ModuleType\n " ,
147
+ " from importlib.abc import Loader\n " ,
148
+ " \n " ,
149
+ " class Module(ModuleType):\n " ,
150
+ " def __init__(self, name):\n " ,
151
+ " self.x = 1\n " ,
152
+ " self.name = name\n " ,
153
+ " \n " ,
154
+ " class ExampleLoader(Loader):\n " ,
155
+ " def create_module(self, spec):\n " ,
156
+ " return Module(spec.name)\n " ,
157
+ " \n " ,
158
+ " def exec_module(self, module):\n " ,
159
+ " module.y = 2\n " ,
160
+ " \n " ,
161
+ " class ExampleFinder(MetaPathFinder):\n " ,
162
+ " def find_spec(self, fullname, path, target=None):\n " ,
163
+ " return ModuleSpec('module', ExampleLoader())\n " ,
164
+ " \n " ,
165
+ " sys.meta_path = [ExampleFinder()]\n " ,
166
+ " \n " ,
167
+ " import module\n " ,
168
+ " print('module', module)\n " ,
169
+ " print('module.name', module.name)\n " ,
170
+ " print('module.x', module.x)\n " ,
171
+ " print('module.y', module.y)\n " ,
172
+ " \n " ,
173
+ " del sys.modules['module']\n " ,
174
+ " \n " ,
175
+ " print('-' * 10)\n " ,
176
+ " module2 = __import__('module')\n " ,
177
+ " \n " ,
178
+ " print('module2 is module?', module2 is module)\n " ,
179
+ " print('module2', module2)\n " ,
180
+ " print('module2.name', module2.name)\n " ,
181
+ " print('module2.x', module2.x)\n " ,
182
+ " print('module2.y', module2.y)\n " ,
183
+ " \n "
184
+ ]
185
+ }
186
+ ]
187
+ }
0 commit comments