Skip to content

Commit cc139a6

Browse files
committed
fix: 🐛 SyntaxError when call traceback
Closes: #49
1 parent 6970950 commit cc139a6

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

pyencrypt/loader.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import linecache
12
import os
23
import sys
34
import traceback
@@ -64,6 +65,9 @@ def check(self) -> bool:
6465
def get_filename(self, fullname: str) -> str:
6566
return self.path
6667

68+
def get_source(self, fullname: str):
69+
return None
70+
6771
def get_data(self, path: _Path) -> bytes:
6872
try:
6973
__n, __d = self.__private_key.split("O", 1)
@@ -76,6 +80,12 @@ def get_data(self, path: _Path) -> bytes:
7680

7781

7882
class EncryptFileFinder(abc.MetaPathFinder, Base):
83+
@staticmethod
84+
def _cache_line(file_path):
85+
stat = os.stat(file_path)
86+
size, mtime = stat.st_size, stat.st_mtime
87+
linecache.cache[file_path] = (size, mtime, [], file_path)
88+
7989
@classmethod
8090
def find_spec(
8191
cls, fullname: str, path: Sequence[_Path], target: types.ModuleType = None
@@ -98,6 +108,9 @@ def find_spec(
98108
file_path = file_path.absolute().as_posix()
99109
if not os.path.exists(file_path):
100110
return None
111+
112+
cls._cache_line(file_path)
113+
101114
loader = EncryptFileLoader(file_path)
102115
return spec_from_loader(name=fullname, loader=loader, origin="origin-encrypt")
103116

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
23
from pyencrypt.encrypt import encrypt_file, encrypt_key, generate_so_file
34
from pyencrypt.generate import generate_aes_key
45
from pyencrypt.license import generate_license_file
@@ -47,7 +48,7 @@ def {function_name}():
4748
# generate loader.so
4849
key = generate_aes_key()
4950
new_path = file_path.with_suffix(".pye")
50-
encrypt_file(file_path, key, new_path=new_path)
51+
encrypt_file(file_path, key.decode(), new_path=new_path)
5152
file_path.unlink()
5253
cipher_key, d, n = encrypt_key(key)
5354
loader_path = generate_so_file(cipher_key, d, n, file_path.parent, license=license)
@@ -58,7 +59,6 @@ def {function_name}():
5859

5960
# License
6061
license and generate_license_file(key.decode(), work_dir, **kwargs)
61-
generate_license_file(key.decode(), work_dir)
6262
return (new_path, loader_path)
6363

6464

tests/test_traceback.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import sys
2+
from pathlib import Path
3+
from typing import Tuple
4+
5+
import pytest
6+
7+
CODE1 = """
8+
try:
9+
a = 1/0
10+
except Exception as e:
11+
import traceback
12+
return traceback.format_exc()
13+
def fun():
14+
return _fun()
15+
"""
16+
17+
18+
@pytest.mark.file(name="file_trace1", function="_fun", code=CODE1)
19+
def test_traceback_format_exc(file_and_loader: Tuple[Path], monkeypatch):
20+
file_path, loader_path = file_and_loader
21+
monkeypatch.syspath_prepend(loader_path.parent.as_posix())
22+
monkeypatch.syspath_prepend(file_path.parent.as_posix())
23+
24+
sys.modules.pop("loader", None)
25+
26+
import loader
27+
from file_trace1 import fun
28+
29+
msg = None
30+
try:
31+
msg = fun()
32+
except Exception:
33+
pass
34+
if not msg:
35+
pytest.fail("`format_exc` return None")
36+
37+
38+
CODE2 = """
39+
try:
40+
a = 1/0
41+
except Exception as e:
42+
import traceback
43+
traceback.print_stack()
44+
def _fun2():
45+
_fun()
46+
def _fun3():
47+
_fun2()
48+
49+
def fun2():
50+
_fun3()
51+
"""
52+
53+
54+
@pytest.mark.file(name="file_trace2", function="_fun", code=CODE2)
55+
def test_traceback_print_stack(file_and_loader: Tuple[Path], monkeypatch, capsys):
56+
file_path, loader_path = file_and_loader
57+
monkeypatch.syspath_prepend(loader_path.parent.as_posix())
58+
monkeypatch.syspath_prepend(file_path.parent.as_posix())
59+
60+
sys.modules.pop("loader", None)
61+
62+
import loader
63+
from file_trace2 import fun2
64+
65+
try:
66+
fun2()
67+
except Exception:
68+
pass
69+
70+
captured = capsys.readouterr()
71+
out = captured.err
72+
73+
assert "in fun" in out
74+
assert "in _fun3" in out
75+
assert "in _fun2" in out
76+
assert "in _fun" in out

0 commit comments

Comments
 (0)