dashingsoft / pyarmor

A tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts.
http://pyarmor.dashingsoft.com
Other
3.46k stars 293 forks source link

[BUG] ImportError: cannot import name 'pyarmor__3' from 'inner2.file2' #1886

Closed evansongandestech closed 4 weeks ago

evansongandestech commented 3 months ago

The following structure: test_dir/ |-- init.py |-- file1.py |-- inner2 | |-- pycache | | -- file2.cpython-39.pyc |-- file2.py -- inner3 |-- __pycache__ |-- file3.cpython-39.pyc `-- file3.py

File 1 is to import function in file2 //////////////// test_dir/init.py: import sys sys.path.append("test_dir") //////////////// test_dir/file1.py: import numpy from inner2.file2 import function_2 def function_1(): return "good" //////////////// inner2/file2.py: import numpy all=['function_2'] def function_2(): return "function_2" //////////////// inner3/file3.py import numpy from inner2.file2 import function_2

all=['function_3'] def function_3(): return "function_3" //////////////// We use rft mode pyarmor gen --enable-rft -r test_dir/

We trace the rft result //////////////// trace.rft test_dir.file1:3 (function_1->pyarmor1) trace.rft test_dir.init:1 (import sys as pyarmor__5) trace.rft test_dir.init:2 (sys->pyarmor5) trace.rft test_dir.inner3.file3:2 (from inner2.file2 import function_2 as pyarmor__3) ////////////////

It seems file3 can import function_2. However file1 cause import error image I want to ask why file2 rewrite to "from inner2.file2 import function_2 as pyarmor__3" but file1 dose not.

jondy commented 3 months ago

Pyarmor 8.5.11 fix one rft issue, please first try this pre-realse version https://pyarmor.dashingsoft.com/downloads/temp/pyarmor-8.5.11.zip

evansongandestech commented 3 months ago

I have tried and install with provided zip. I still get import error while I want to import function_1 in file1.py

from test_dir.file1 import function_1 ImportError: cannot import name 'pyarmor__3' from 'inner2.file2' (/home/evansong/pyarmor-test/dist/test_dir/inner2/file2.py)

In the trace log,
trace.rft test_dir.file1:3 (function_1->pyarmor1) trace.rft test_dir.init:1 (import sys as pyarmor__5) trace.rft test_dir.init:2 (sys->pyarmor5) trace.rft test_dir.inner3.file3:2 (from inner2.file2 import function_2 as pyarmor__3)

"from inner2.file2 import function_2" in file1.py doesn't convert to "from inner2.file2 import function_2 as pyarmor__3".

jondy commented 3 months ago

I do a similar test, but can't reproduce it.

My suggestion is

  1. First upgrade pyarmor 8.5.11, which has been released yesterday.
  2. Remove current path .pyarmor, make sure there is no unexpected local settings.
  3. Also enable rft_simple_import for test, for example
    pyarmor cfg enable_trace=1
    pyarmor cfg trace_rft=1
    pyarmor cfg rft_simple_import=1
  4. After obfuscate the scripts, check the reformed script in the path .pyarmor/rft/

And now pyarmor rft mode doesn't work well with extra Python path.

In this case, module inner.file2 is taken as test_dir.inner.file2 by Pyarmor RFT mode.

RFT mode will support multiple Python Path in next major version 8.6, now it's still developing.

jondy commented 4 weeks ago

Refer to #1964, the feature is used to refact complex project which need extra sys.path to run the script