[BUG] Can't use obfuscated scripts under path that contain Chinese character
Scripts obfuscated by pyarmor works fine under path that with only ascii-character. But when I moved it to the path contains Chinese character, it won't work anymore with error message.
UnicodeDecodeError: 'mbcs' codec can't decode bytes in position 0--1: No mapping for the Unicode character exists in the target code page.
here is my file structure +D:/測試檔案/test/ |-+my_pyarmor_test.py |-+my_pyarmor_test_second.py
which contains following content
#### my_pyarmor_test.py
import os
def FunctionName():
from my_pyarmor_test_second import class_b
class_b.haha()
print('hello world')
FunctionName()
#### my_pyarmor_test_second.py
class class_b():
inner_value = 20
@classmethod
def haha(cls):
print('inner_value',cls.inner_value)
Note that I'm running pyarmor on python version 35 (which is my use case ). but pyarmor it self is installed under path of Python38. the command I use in the following line
C:/Users/Graphics/AppData/Local/Programs/Python/Python35/python.exe C:/Users/Graphics/AppData/Local/Programs/Python/Python38/Lib/site-packages/pyarmor/pyarmor.py obfuscate --recursive D:/測試檔案/test/
here is PyArmor INFO message
INFO PyArmor Version 7.6.0
INFO Python 3.5.0
INFO Target platforms: Native
INFO Source path is "D:\blenderh測試檔案\20220818\pyarmor_test"
INFO Entry scripts are []
INFO Use cached capsule C:\Users\Graphics\.pyarmor\.pyarmor_capsule.zip
INFO Search scripts mode: Recursive
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 Obfuscate string value is False
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 C:\Users\Graphics\AppData\Local\Programs\Python\Python38\Lib\site-packages\pyarmor\platforms\windows\x86_64\_pytransform.dll
INFO Patch library dist\pytransform\_pytransform.dll
INFO Patch library file OK
INFO Copying C:\Users\Graphics\AppData\Local\Programs\Python\Python38\Lib\site-packages\pyarmor\pytransform.py
INFO Rename it to pytransform/__init__.py
INFO Generate runtime files OK
INFO Start obfuscating the scripts...
INFO my_pyarmor_test.py -> dist\my_pyarmor_test.py
INFO my_pyarmor_test_second.py -> dist\my_pyarmor_test_second.py
INFO Obfuscate 2 scripts OK.
than I copied the obfuscated file to form the following file structure
+D:/測試檔案/dest/
| - +pytransform <- created by PyArmor
| |-+__init__.py
| |-+_pytransform.dll
|-+my_pyarmor_test.py
|-+my_pyarmor_test_second.py
running the following command will get the error
python D:/測試檔案/dest/my_pyarmor_test.py
something worth noting
- my operation system is Windows 10
- not all Chinese characters will lead to this error, it needs to be a certain combination such as '測試檔案'
- the simplest test case I can make require import another obfuscated python file.
Is there any way to solve this issue?
Try to make a link to the source path, for example,
mklink /d src D:/測試檔案/dest
pyarmor obfuscate -r src
I have tried this but it raised another problem.
After creating link under the path and run the code (Noted that the path is a python script rather than a folder which I say it wrong last time)
mklink /d src D:\測試檔案\test\
C:/Users/Graphics/AppData/Local/Programs/Python/Python35/python.exe C:/Users/Graphics/AppData/Local/Programs/Python/Python38/Lib/site-packages/pyarmor/pyarmor.py obfuscate --recursive src/my_pyarmor_text.py
The content of the script is different and raised error when running the python script
#### my_pyarmor_test.py
from pytransform import pyarmor_runtime #<- won't have this line if obfuscate through link path
pyarmor_runtime() #<- won't have this line if obfuscate through link path
__pyarmor__(__name__, __file__, b'\x50......\x61', 2)
Following error message
PS D:\測試檔案\dist> python D:\測試檔案\dist\my_pyarmor_test.py <-- running python script
Traceback (most recent call last):
File "D:\測試檔案\dist\my_pyarmor_test.py", line 1, in <module>
__pyarmor__(__name__, __file__, b'\x50......\x61', 2)
NameError: name '__pyarmor__' is not defined
Thanks for your reply, but is there any way to fix this?
Please read this page for this problem https://pyarmor.readthedocs.io/en/latest/questions.html
I've tried making a link and do it again but still got the same error.
UnicodeDecodeError: 'mbcs' codec can't decode bytes in position 0--1: No mapping for the Unicode character exists in the target code page.
Run pyarmor command with option -d to get traceback, and where to raise this exception?
I did not get any exception raised when obfuscate script with pyarmor. The error is coming from running the obfuscated script under the path contains Chinese character.
After reading the first report, I find the problem. Try to run a normal python script in Chinese path, it will report the same issue. So it's Python's issue
It sound odd. If not obfuscated, I did not get the error with the script I used in the first comment.
Does it mean the script obfuscated by pyarmor may not work in that situation?
Do you use outer license? If not, try to hack D:/測試檔案/dest/pytransform/__init__.py
at line 331 in _load_library
- m.set_option(1, path.encode() if sys.version_info[0] == 3 else path)
+ pass # m.set_option(1, path.encode() if sys.version_info[0] == 3 else path)
I'm not using outer license. And I still got the error after hack the pytransform/__init__.py file.
The error seems not came from pyarmor_runtime() but __pyarmor__() in the obfuscated script.
I test it in Win 7, just run an obfuscated scripts in the path 測試檔案, it works fine.
I have no win10. Could you do a simple test, replace __file__ with string constant `"test.py" in the obfuscated scripts, and run it again.
If there is restrict error, obfuscate script with extra option --restrict 0
I've tried replace __file__ with "test.py" constant, and get restrict error. After obfuscate the script with restrict 0 and doing it again, the code is running correctly!
Does replacing __file__ with "test.py" constant change obfuscate code's behavior?
It seems the pyarmor() function can not take Chinese characters as __file__ value, and it does look like Python's issue.
I can work around this problem by predefined __file__ inside my script before obfuscate and then replacing __file__ with an empty string and it worked under my use case.
import os #<- added text
__file__ = os.getcwd() + '/somepath/script.py' #<- added text
... #reset of script
However, I wish there was a way to not do this as it uses os.getcwd() and may not work in some cases.
Does replacing file with "test.py" constant change obfuscate code's behavior?
No. It almost not.