-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathmain.py
More file actions
executable file
·455 lines (295 loc) · 10.5 KB
/
main.py
File metadata and controls
executable file
·455 lines (295 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
#!/usr/bin/env python
import os
import sys
if '##__init__ ##module':
# A *module* is either:
# - a `.py` or `.pyc` file
# - dir with and `__init__.py`
# `__init__.py` code is executed when the module is loaded,
# Just like code in a file is executed when it is loaded
# It is not possible to distinguish between both except by looking at <#__file__>
import a
assert a.f() == 'a.f()'
assert a.C().m() == 'a.C.m()'
import d
assert d.f() == 'd.f()'
if '##module search path':
# View current python module search path:
print sys.path
if '##append to module search path':
if '##environment variable':
# Simplest way to change path for all system.
# Change this variable in `bashrc`.
# A bit platform dependent (harder to to in windows...).
if 'PYTHONPATH' in os.environ:
print os.environ['PYTHONPATH']
#`:` separated list of paths to search for *before* other paths
#- has higher precedence than installation default paths (`/usr/lib/pythonX.X/`)
#- has lower precedence than stuff installed with `pip` or `setup.py`: `/usr/local/lib/python2.7/dist-packages/`
if '##site package':
pass
#- applies to all system
#- less platform dependent
#goes after `PYTHONPATH`
#USER_SITE="$(python -c $'import site\nprint site.USER_SITE')"
#NEW_PATH="`mktemp -d`"
#echo "$NEW_PATH" > "$USER_SITE"/anything.pth
#echo 'a = 123456' > "$NEW_PATH"/innewpath.py
#python -c $'import innewpath\nprint innewpath.a'
if "##sys.path":
# Set search path on a per program basis:
sys.path.append('/the/new/path')
sys.path.insert(0, '/the/new/path')
# Doing this will also change the system path on modules
# imported by this module:
import a
assert a.syspath == sys.path
# Remember that doing:
#sys.path = ['.']
# TODO: how does that work for sys.path? It does not work for other lists.
import contains_list
contains_list.l[0] = 1
import a
if "##import":
if "Imports of imports are not imported":
# Imports inside imports are not put in current namespace.
# Even if module `imported_from_a` was imported in a, it is not defined here!
import a
try:
imported_from_a.n
except NameError:
pass
else:
assert False
# Therefore, this is not the same as copying code from the module and pasting here
# as a c include does!
# If you really want to copy code from a file and execute it use <#execfile>
if "##relative imports":
# Only work inside dirs structure with `__init__` files, that is, submodule structure
if "##Can't call method from d.a by importing only d but not importing d.a":
import d
try:
d.a.f()
except AttributeError:
pass
else:
assert False
import d.a2
assert d.a2.f() == "d.a2.f()"
import d.d2.a3
assert d.d2.a3.f() == "d.d2.a3.f()"
if "Can only be done inside module structure":
try:
from . import re
assert re.f() == "re.f()"
except ValueError:
pass
else:
assert False
# Does not work here because we have no `__init__.py` in current dir!
# See <#/d/d/d/a> for an example
if "Can only import modules, not their attributes":
try:
import a.f
except ImportError:
pass
else:
assert False
if "Go up on module structure":
pass
# Up once:
#from .. import a
#a.f()
# Up two modules:
#from ... import a
#a.f()
# Up three modules:
#from .... import a
#a.f()
if "##from":
from d import a2
assert a2.f() == "d.a2.f()"
#can also be used to import module contents:
from a import f
assert f() == 'a.f()'
if '##star ##*':
# Never use this except for bad practice.
# Makes it very hard to know what is being imported or not and what is its name!
from d import *
assert a2.f() == "d.a2.f()"
assert d2.f() == "d.d2.f()"
# Can also be used to import module contents:
from a import *
assert f() == 'a.f()'
assert g() == 'a.g()'
# If module is a dir, imports both its:
from d import *
assert f() == 'd.f()'
assert a2.f() == 'd.a2.f()'
assert d2.f() == 'd.d2.f()'
# Will import nothing, since a has no submodules.
if '##as':
from a import f as g
assert g() == 'a.f()'
# ERROR:
#from d import d as d2
#import d2.d
# Must use import `d.d.d`
##multiline
from d import (
a2,
d2,
)
if 'Stuff defined in import overrides definitions of importer scope':
# First define some names on current scope:
import imported_from_main
a = 'a'
def f():
return 'f()'
# Now the import will override them:
import a
assert a.a == 'a.a'
assert a.f() == 'a.f()'
if 'You can reassign what modules symbols mean':
"""
Once imported, a module is just another dict like namespace,
and you can edit it was you wish in the current namespace.
Those changes will not however reflect on other modules that imported that module!
"""
a.a = 1
assert a.a == 1
a = 2
assert a == 2
# Reassign on parent modules disables the children also:
import d
import d.a
d = 1
try:
d.a
except AttributeError:
pass
else:
assert False
if 'Uncaught ##exceptions at imported blow up at importer':
try:
import raise_exception
except Exception:
pass
else:
assert False
if '##__import__':
'''
Backend for the `import` statement.
Import module with name that cannot be variable, e.g. hyphens in executables:
test_mod = __import__('test-mod')
'''
if '##circular import':
"""
Modules are only evaluated once in import.
So this can lead cannot import errors.
"""
if 'Magic methods dont work':
try:
assert a() == 'a.__call__()'
except TypeError:
pass
else:
assert False
if '##submodules':
if 'Submodule vs attribute':
# *never define in your __init__ file an attribute which has the same name as a module*
import d.a
assert d.a.a == 'd.a'
#TODO1
import d
#assert d.a == 'd.a'
if '##importing a submodule also imports parent':
d = 1
try:
assert d.a == 'd.a'
except AttributeError:
pass
except:
assert False
#TODO2 related to TODO1
import d.a2
#assert d.a == 'd.a'
if '##Inform end user that package is missing.':
"""
try:
import bs4
except ImportError:
print 'ERROR: Missing dependencies. Install with:\n\nsudo pip install -r requirements.txt'
sys.exit(1)
"""
if '##module attributes':
# https://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy
if '##__file__ ##file':
"""
Contains the full path of a file.
Only defined for imported modules.
Not defined on the file script being executed run!
Possible reason: modules are always loaded from files,
while scripts may exist in RAM only:
#echo 'print __file__' | python
"""
# Check if a module is in path and if yes print its path:
try:
import os
except:
print 'not found'
else:
print os.__file__
if '##__name__':
# If file was imported, TODO.
# If the file is being executed it equals '__main__'.
import a
assert a.__name__ == 'a'
import d.a2
assert d.a2.__name__ == 'd.a2'
import a as b
assert b.__name__ == 'a'
assert __name__ == '__main__'
if '##symlink':
# Acts exactly as files that have the same content as their destination.
# Can even link to non `.py` files:
import a
import aln
assert aln.a == 'a'
assert os.path.splitext( aln.__file__ )[0] == os.path.join( os.path.dirname( a.__file__ ), 'aln' )
import d.aln
assert d.aln.a == 'a'
assert os.path.splitext( d.aln.__file__ )[0] == os.path.join( os.path.dirname( a.__file__ ), 'd', 'aln' )
if '##execfile':
# Copy contents of file and exec them here
# Same as `exec(read('file.py'))`
defined_in_execed = 0
execfile('execed.py')
assert defined_in_execed == 1
# Paths are either absolute or relative to `os.getcwd()`!
# Usually a bad idea for the same reason that `from BLA import *` is a bad idea.
# Always prefer: `from module import var1, var2`,
# so that you keep control of what is being imported.
if '##imp':
# Do explicit import / find in path operations.
import imp
# Import relative from *os.getcwd()*, *not* to location of this file:
try:
b = imp.load_source('c', 'a.py')
except IOError:
# Raised if file not found.
pass
assert b.f() == 'a.f()'
assert b.__name__ == 'c'
# In practice this is unusable as it fails for requires that require other files:
# http://stackoverflow.com/questions/9066777/howto-import-modules-with-dependencies-in-the-same-absolute-relative-path
# The best thing to do is to play with the path.
# Create a new empty module:
dynamic_module = imp.new_module('dynamic_module_name')
assert dynamic_module.__name__ == 'dynamic_module_name'
##__dict__ and modules
import dict_cheat
for k in dict_cheat.__dict__:
print k
print dict_cheat.__dict__[k]
print 30 * '='