4
4
5
5
# Standard modules
6
6
import asyncio
7
- import cgitb
8
7
import code
9
8
import collections
10
9
import copy
49
48
gunicorn = None
50
49
51
50
import click
51
+
52
52
# Third party modules
53
53
import ombott as bottle
54
54
import pluralize
@@ -144,6 +144,15 @@ def module2filename(module):
144
144
return filename
145
145
146
146
147
+ def load_module (name , path ):
148
+ """load a module with name from math"""
149
+ spec = importlib .util .spec_from_file_location (name , path )
150
+ module = importlib .util .module_from_spec (spec )
151
+ sys .modules [name ] = module
152
+ spec .loader .exec_module (module )
153
+ return module
154
+
155
+
147
156
def required_folder (* parts ):
148
157
"""joins the args and creates the folder if not exists"""
149
158
path = os .path .join (* parts )
@@ -302,7 +311,6 @@ def dumps(obj, sort_keys=True, indent=2):
302
311
303
312
304
313
class Fixture :
305
-
306
314
__request_master_ctx__ = threading .local ()
307
315
__fixture_debug__ = False
308
316
@@ -542,7 +550,6 @@ def render(
542
550
543
551
544
552
class Template (Fixture ):
545
-
546
553
cache = Cache (100 )
547
554
548
555
def __init__ (self , filename , path = None , delimiters = "[[ ]]" ):
@@ -579,7 +586,6 @@ def on_success(self, context):
579
586
580
587
581
588
class Session (Fixture ):
582
-
583
589
# All apps share the same default secret if not specified.
584
590
# important for _dashboard reload
585
591
# the actual value is loaded from a file
@@ -649,6 +655,8 @@ def load(self):
649
655
if self .storage :
650
656
token_data = raw_token .encode ()
651
657
json_data = self .storage .get (token_data )
658
+ if isinstance (json_data , bytes ):
659
+ json_data = json_data .decode ("utf8" )
652
660
if json_data :
653
661
self_local .data = json .loads (json_data )
654
662
else :
@@ -869,7 +877,6 @@ def uses(*fixtures_in):
869
877
fixtures .append (fixture )
870
878
871
879
def decorator (func ):
872
-
873
880
if Fixture .__fixture_debug__ :
874
881
# in debug mode log all calls to fixtures
875
882
def call (f , context ):
@@ -1028,7 +1035,7 @@ def new_sslwrap(
1028
1035
1029
1036
1030
1037
def get_error_snapshot (depth = 5 ):
1031
- """Return a dict describing a given traceback (based on cgitb.text) ."""
1038
+ """Return a dict describing a given traceback."""
1032
1039
1033
1040
tb = traceback .format_exc ()
1034
1041
errorlog = os .environ .get ("PY4WEB_ERRORLOG" )
@@ -1234,7 +1241,6 @@ def write(self, *args, **kwargs):
1234
1241
1235
1242
1236
1243
class Reloader :
1237
-
1238
1244
ROUTES = collections .defaultdict (list )
1239
1245
MODULES = {}
1240
1246
ERRORS = {}
@@ -1272,8 +1278,7 @@ def import_apps():
1272
1278
# if first time reload dummy top module
1273
1279
if not Reloader .MODULES :
1274
1280
path = os .path .join (folder , "__init__.py" )
1275
- loader = importlib .machinery .SourceFileLoader ("apps" , path )
1276
- loader .load_module ()
1281
+ module = load_module ("apps" , path )
1277
1282
# Then load all the apps as submodules
1278
1283
if os .environ .get ("PY4WEB_APP_NAMES" ):
1279
1284
app_names = os .environ .get ("PY4WEB_APP_NAMES" ).split ("," )
@@ -1292,7 +1297,6 @@ def import_app(app_name, clear_before_import=True):
1292
1297
init = os .path .join (path , "__init__.py" )
1293
1298
1294
1299
if os .path .isdir (path ) and not path .endswith ("__" ) and os .path .exists (init ):
1295
-
1296
1300
action .app_name = app_name
1297
1301
module_name = "apps.%s" % app_name
1298
1302
@@ -1320,9 +1324,7 @@ def clear_modules():
1320
1324
buf_out = StreamProxy (io .StringIO ())
1321
1325
buf_err = StreamProxy (buf_out ._stream )
1322
1326
with redirect_stdout (buf_out ), redirect_stderr (buf_err ):
1323
- module = importlib .machinery .SourceFileLoader (
1324
- module_name , init
1325
- ).load_module ()
1327
+ module = load_module (module_name , init )
1326
1328
load_module_message = buf_out ._stream .getvalue ()
1327
1329
buf_out ._stream .close ()
1328
1330
buf_out ._stream = sys .stdout
0 commit comments