inspect.stack() causes error on Python 3.10
Description
OS: Ubuntu 20.04 Python: 3.10.4 PyArmor: 7.4.2
- create a venv and install pyarmor
python3.10 -m venv venv
venv/bin/pip install pyarmor
- Prepare a python file (
main.py) as follows
import inspect
inspect.stack()
- Obfuscate
main.py
venv/bin/pyarmor obfuscate main.py
>>>
INFO PyArmor Trial Version 7.4.2
INFO Python 3.10.4
INFO Target platforms: Native
INFO Source path is "/home/du/workspace/pyarmor_test"
INFO Entry scripts are ['main.py']
INFO Use cached capsule /home/du/.pyarmor/.pyarmor_capsule.zip
INFO Search scripts mode: Normal
INFO Save obfuscated scripts to "dist"
INFO Read product key from capsule
INFO Obfuscate module mode is 2
INFO Obfuscate code mode is 1
INFO Wrap mode is 1
INFO Restrict mode is 1
INFO Advanced value is 0
INFO Super mode is False
INFO Super plus mode is not enabled
INFO Generating runtime files to dist/pytransform
INFO Extract pytransform.key
INFO Read default license from capsule
INFO Copying /home/du/workspace/pyarmor_test/venv/lib/python3.10/site-packages/pyarmor/platforms/linux/x86_64/_pytransform.so
INFO Patch library dist/pytransform/_pytransform.so
INFO Patch library file OK
INFO Copying /home/du/workspace/pyarmor_test/venv/lib/python3.10/site-packages/pyarmor/pytransform.py
INFO Rename it to pytransform/__init__.py
INFO Generate runtime files OK
INFO Start obfuscating the scripts...
INFO main.py -> dist/main.py
INFO Insert bootstrap code to entry script dist/main.py
INFO Obfuscate 1 scripts OK.
- Run obfuscated script and get error
venv/bin/python dist/main.py
>>>
Traceback (most recent call last):
File "</home/du/workspace/pyarmor_test/dist/main.py>", line 3, in <module>
File "<frozen main>", line -1, in <module>
File "/usr/local/lib/python3.10/inspect.py", line 1678, in stack
return getouterframes(sys._getframe(1), context)
File "/usr/local/lib/python3.10/inspect.py", line 1655, in getouterframes
frameinfo = (frame,) + getframeinfo(frame, context)
File "/usr/local/lib/python3.10/inspect.py", line 1627, in getframeinfo
start = lineno - 1 - context//2
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
Note that this error does not occurs when I use Python 3.9.x .
For inspect.stack and any function to visit python runtime frame, the obfuscated scripts could not make sure it works. Though it works in some python version, it may not work in other versions. I'll not fix this kind of issue.
A number of things break due to lineno not being made available. Would it be possible to have Pyarmor simply return a dummy value, like -1? Then there is a higher chance that thing might not completely blow up when some third party code calls inspect.*, which is outside of our control.
I've been hit by this problem on a number of occasions already. One is coming from pandas' deprecation warnings (it tries to be friendly by showing you which line the offending code is), when it does, my app just bombs out. The other problem is with pytest - if any of the code calls logging.exception(...), then pytest simply blows up, which is unfortunately because I'm really keen to unit test my post-obfuscated code to make sure things actually work..
It seems Pyarmor 8.0 could work with this example. I just test with Python 3.10 with this main.py
pyarmor gen main.py
python3.10 dist/main.py