Skip to content

Commit dad8e0f

Browse files
committed
added support for python 3.11
1 parent 52df54d commit dad8e0f

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

.travis.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ cache: pip
44
language: python
55

66
python:
7-
- "3.6"
87
- "3.7"
98
- "3.8"
9+
- "3.9"
10+
- "3.10"
11+
- "3.11"
1012

1113
script:
1214
- make test

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ docs: venv
2323
cd docs; . ../venv/bin/activate && ./updateDocs.sh html
2424
test: venv
2525
venv/bin/pip install -U -r test-requirements.txt
26-
venv/bin/python -m pytest --cov=py4web --cov-report html:cov.html -v -s tests/
26+
venv/bin/python -m pytest --cov=py4web --cov-report html:cov.html -v tests/
2727
setup:
2828
venv/bin/python py4web.py setup apps
2929
venv/bin/python py4web.py set_password

py4web/core.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
# Standard modules
66
import asyncio
7-
import cgitb
87
import code
98
import collections
109
import copy
@@ -49,6 +48,7 @@
4948
gunicorn = None
5049

5150
import click
51+
5252
# Third party modules
5353
import ombott as bottle
5454
import pluralize
@@ -144,6 +144,15 @@ def module2filename(module):
144144
return filename
145145

146146

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+
147156
def required_folder(*parts):
148157
"""joins the args and creates the folder if not exists"""
149158
path = os.path.join(*parts)
@@ -302,7 +311,6 @@ def dumps(obj, sort_keys=True, indent=2):
302311

303312

304313
class Fixture:
305-
306314
__request_master_ctx__ = threading.local()
307315
__fixture_debug__ = False
308316

@@ -542,7 +550,6 @@ def render(
542550

543551

544552
class Template(Fixture):
545-
546553
cache = Cache(100)
547554

548555
def __init__(self, filename, path=None, delimiters="[[ ]]"):
@@ -579,7 +586,6 @@ def on_success(self, context):
579586

580587

581588
class Session(Fixture):
582-
583589
# All apps share the same default secret if not specified.
584590
# important for _dashboard reload
585591
# the actual value is loaded from a file
@@ -649,6 +655,8 @@ def load(self):
649655
if self.storage:
650656
token_data = raw_token.encode()
651657
json_data = self.storage.get(token_data)
658+
if isinstance(json_data, bytes):
659+
json_data = json_data.decode("utf8")
652660
if json_data:
653661
self_local.data = json.loads(json_data)
654662
else:
@@ -869,7 +877,6 @@ def uses(*fixtures_in):
869877
fixtures.append(fixture)
870878

871879
def decorator(func):
872-
873880
if Fixture.__fixture_debug__:
874881
# in debug mode log all calls to fixtures
875882
def call(f, context):
@@ -1028,7 +1035,7 @@ def new_sslwrap(
10281035

10291036

10301037
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."""
10321039

10331040
tb = traceback.format_exc()
10341041
errorlog = os.environ.get("PY4WEB_ERRORLOG")
@@ -1234,7 +1241,6 @@ def write(self, *args, **kwargs):
12341241

12351242

12361243
class Reloader:
1237-
12381244
ROUTES = collections.defaultdict(list)
12391245
MODULES = {}
12401246
ERRORS = {}
@@ -1272,8 +1278,7 @@ def import_apps():
12721278
# if first time reload dummy top module
12731279
if not Reloader.MODULES:
12741280
path = os.path.join(folder, "__init__.py")
1275-
loader = importlib.machinery.SourceFileLoader("apps", path)
1276-
loader.load_module()
1281+
module = load_module("apps", path)
12771282
# Then load all the apps as submodules
12781283
if os.environ.get("PY4WEB_APP_NAMES"):
12791284
app_names = os.environ.get("PY4WEB_APP_NAMES").split(",")
@@ -1292,7 +1297,6 @@ def import_app(app_name, clear_before_import=True):
12921297
init = os.path.join(path, "__init__.py")
12931298

12941299
if os.path.isdir(path) and not path.endswith("__") and os.path.exists(init):
1295-
12961300
action.app_name = app_name
12971301
module_name = "apps.%s" % app_name
12981302

@@ -1320,9 +1324,7 @@ def clear_modules():
13201324
buf_out = StreamProxy(io.StringIO())
13211325
buf_err = StreamProxy(buf_out._stream)
13221326
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)
13261328
load_module_message = buf_out._stream.getvalue()
13271329
buf_out._stream.close()
13281330
buf_out._stream = sys.stdout

0 commit comments

Comments
 (0)