Skip to content

Commit de4f954

Browse files
committed
Doc option --pack new usage
1 parent 7f1cef1 commit de4f954

File tree

4 files changed

+139
-40
lines changed

4 files changed

+139
-40
lines changed

docs/reference/man.rst

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Generate obfuscated scripts and all the required runtime files.
149149
--assert-import assert module is obfuscated :option:`... <--assert-import>`
150150
--assert-call assert function is obfuscated :option:`... <--assert-call>`
151151

152-
--pack BUNDLE repack bundle with obfuscated scripts :option:`... <--pack>`
152+
--pack <onefile|onedir> Obfuscate scripts then pack :option:`... <--pack>`
153153

154154
--use-runtime PATH use shared runtime package :option:`... <--use-runtime>`
155155

@@ -562,19 +562,33 @@ The function :func:`__assert_armored__` is a builtin function in obfuscated scri
562562

563563
This option neither touches statement ``from import``, nor the module imported by function ``__import__``.
564564

565-
.. option:: --pack BUNDLE
565+
.. option:: --pack <onefile,onedir>
566566

567-
Repack bundle with obfuscated scripts
567+
Obfuscate script first, then pack the obfuscated scripts to bundle
568568

569-
Here ``BUNDLE`` is an executable file generated by PyInstaller_
569+
.. versionchanged:: 8.5.4
570570

571-
Pyarmor just obfuscates the script first.
571+
Before v8.5.4, user need first generate an executable file by PyInstaller_
572572

573-
Then unpack the bundle.
573+
Now everything is done by Pyarmor
574574

575-
Next replace all the ``.pyc`` in the bundle with obfuscated scripts, and append all the :term:`runtime files` to the bundle.
575+
The old method still works, but it's deprecated.
576576

577-
Finally repack the bundle and overwrite the original ``BUNDLE``.
577+
Once this option is used, pyarmor will analysis the source of main script, and find all the imported modules and packages which are in the same path of main script. All of these used modules and packages will be obfuscated automatically
578+
579+
Then pyarmor will call PyInstaller_ to pack the obfuscated scripts to one file or one folder bundle.
580+
581+
For example, generate one file bundle::
582+
583+
pyarmor gen --pack onefile foo.py
584+
585+
ls dist/
586+
587+
Sometimes it need specify option :option:`-r` to make sure all the child packages are obfuscated. For example::
588+
589+
pyarmor gen --pack onefolder -r foo.py
590+
591+
.. seealso:: :doc:`../topic/repack`
578592

579593
.. option:: --use-runtime PATH
580594

@@ -759,7 +773,7 @@ Set option to boolean value::
759773
$ pyarmor cfg wrap_mode 0
760774
$ pyarmor cfg wrap_mode=1
761775

762-
Set option to string value::
776+
Set option to string value, it must leave blank around ``=``::
763777

764778
$ pyarmor cfg outer_keyname "sky.lic"
765779
$ pyarmor cfg outer_keyname = "sky.lic"

docs/topic/repack.rst

Lines changed: 96 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,86 @@ Insight Into Pack Command
66

77
.. program:: pyarmor gen
88

9-
Pyarmor 8.0 has no command pack, but option :option:`--pack`. It could specify an executable file generated by PyInstaller_::
9+
Pyarmor 8.0 has no command pack, but option :option:`--pack`, once it's set, pyarmor will automatically pack the scripts into one bundle.
1010

11-
pyinstaller foo.py
12-
pyarmor gen --pack dist/foo/foo foo.py
11+
Packing Scripts Automatically
12+
=============================
1313

14-
If this option isn't set, pyarmor only obfuscates the scripts.
14+
.. versionadded:: 8.5.4
1515

16-
If this option is set, pyarmor first obfuscates the scripts, then does extra work:
16+
It accept 2 values: ``onefile`` and ``onedir``, just as PyInstaller_
1717

18-
* Unpacking this executable to a temporary folder
19-
* Replacing the scripts in bundle with obfuscated ones
20-
* Appending runtime files to the bundle in this temporary folder
21-
* Repacking this temporary folder to an executable file and overwrite the old
18+
Actually Pyarmor need call PyInstaller_ to generate final bundle, so first install PyInstaller_::
2219

23-
In Darwin, let obfuscated scripts work in both intel and Apple Silicon by extra option ``--platform darwin.x86_64,darwin.arm64``::
20+
pip install pyinstaller
2421

25-
pyarmor gen --pack dist/foo/foo --platform darwin.x86_64,darwin.arm64 foo.py
22+
Suppose our project tree like this::
2623

27-
.. important::
24+
project/
25+
├── foo.py
26+
├── queens.py
27+
└── joker/
28+
├── __init__.py
29+
├── queens.py
30+
└── config.json
2831

29-
Only listed scripts are obfuscated, if need obfuscate more scripts and sub packages, list all of them in command line. For example::
32+
Let's check what happens when the following commands are executed::
3033

31-
pyarmor gen --pack dist/foo/foo -r *.py dir1 dir2 ...
34+
cd project
35+
pyarmor gen --pack onefile foo.py
36+
37+
1. Pyarmor first open `foo.py`, then find it need `queens.py` and package `joker`
38+
2. Then obfuscate all of them to one temporary path `.pyarmor/pack/dist`
39+
3. Next pyarmor call PyInstaller with plain script `foo.py`, to get all the system packages used by `foo.py`, and save all of them to hiddenimports table.
40+
4. Finally pyarmor call PyInstaller again but with obfuscated scripts and all of hidden imports to generate final bundle.
41+
42+
Now let's run the final bundle, it's `dist/foo` or `dist/foo.exe`::
43+
44+
ls dist/foo
45+
dist/foo
46+
47+
If need one folder bundle, just pass `onedir` to pack::
48+
49+
pyarmor gen --pack onedir foo.py
50+
ls dist/foo
51+
dist/foo/foo
52+
53+
Checking Obfuscated Scripts Have Been Packed
54+
--------------------------------------------
55+
56+
Add one line in the script ``foo.py`` or ``joker/__init__.py``
57+
58+
.. code-block:: python
59+
60+
print('this is __pyarmor__', __pyarmor__)
61+
62+
If it's not obfuscated, the final bundle will raise error. Because builtin name ``__pyarmor__`` is only available in the obfuscated scripts.
63+
64+
Using More PyInstaller Options
65+
------------------------------
66+
67+
If need extra PyInstaller options, using configuration item ``pack:pyi_options``. For example, reset it with one PyInstaller option ``-w``::
68+
69+
pyarmor cfg pack:pyi_options = "-w"
70+
71+
Let's append another option ``-i``, note that it must be one whitespace between option ``-i`` and its value, do not use ``=``. For example::
72+
73+
pyarmor cfg pack:pyi_options ^ "-i favion.ico"
74+
75+
Append another option::
76+
77+
pyarmor cfg pack:pyi_options ^ "--add-data joker/config.json:joker"
78+
79+
.. seealso:: :ref:`pyarmor cfg`
80+
81+
Using More Obfuscation Options
82+
------------------------------
83+
84+
In Darwin, let obfuscated scripts work in both intel and Apple Silicon by extra option ``--platform darwin.x86_64,darwin.arm64``::
85+
86+
pyarmor gen --pack onefile --platform darwin.x86_64,darwin.arm64 foo.py
87+
88+
You can use any other obfuscation options to improve security, but some of them may not work. For example, :option:`--restrict` can't be used with :option:`--pack`.
3289

3390
Packing obfuscated scripts manually
3491
===================================
@@ -134,6 +191,31 @@ If it's not obfuscated, the final bundle will raise error.
134191
.. [#] Just let PyInstaller could find runtime package without extra pypath
135192
.. [#] Most of the other PyInstaller options could be used here
136193
194+
Packing with PyInstaller Bundle
195+
===============================
196+
197+
.. deprecated:: 8.5.4
198+
199+
Use :option:`--pack` ``onefile`` or ``onedir`` instead.
200+
201+
The option :option:`--pack` also could accept an executable file generated by PyInstaller_::
202+
203+
pyinstaller foo.py
204+
pyarmor gen --pack dist/foo/foo foo.py
205+
206+
But only PyInstaller < 6.0 works by this method. If this option is set, pyarmor first obfuscates the scripts, then:
207+
208+
* Unpacking this executable to a temporary folder
209+
* Replacing the scripts in bundle with obfuscated ones
210+
* Appending runtime files to the bundle in this temporary folder
211+
* Repacking this temporary folder to an executable file and overwrite the old
212+
213+
.. important::
214+
215+
Only listed scripts are obfuscated, if need obfuscate more scripts and sub packages, list all of them in command line. For example::
216+
217+
pyarmor gen --pack dist/foo/foo -r *.py dir1 dir2 ...
218+
137219
Segment fault in Apple M1
138220
=========================
139221

docs/tutorial/obfuscation.rst

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -286,41 +286,45 @@ And then obfuscate the scripts again.
286286
Packing obfuscated scripts
287287
==========================
288288

289-
Pyarmor need PyInstaller to pack scripts first, then replace plain scripts with obfuscated ones in bundle.
289+
Pyarmor need PyInstaller to pack the obfuscated scripts, so first make sure PyInstaller has been installed. If not, simple install it by this command::
290+
291+
pip install pyinstaller
290292

291293
Packing to one file
292294
-------------------
293295

294-
First packing script to one file by PyInstaller with option ``-F``::
296+
.. versionchanged:: 8.5.4
297+
298+
Before v8.5.4, it need more work, please check old version documentation (v8.5.3).
295299

296-
$ pyinstaller -F foo.py
300+
Packing script to one file only need one command::
297301

298-
It generates one bundle file ``dist/foo``, pass this to pyarmor::
302+
pyarmor gen --pack onefile foo.py
299303

300-
$ pyarmor gen -O obfdist --pack dist/foo foo.py
304+
Run the final bundle::
301305

302-
This command will obfuscate ``foo.py`` first, then repack ``dist/foo``, replace the original ``foo.py`` with ``obfdist/foo.py``, and append all the runtime files to bundle.
306+
dist/foo
303307

304-
The final output is still ``dist/foo``::
308+
Pyarmor will automatically obfuscate `foo.py` and all the other used modules and packages in the same path, then pack the obfuscated to one bundle.
305309

306-
$ dist/foo
310+
.. important::
311+
312+
Please pass plain script in command line, for example, `foo.py` should not been obfuscated.
307313

308314
Packing to one folder
309315
---------------------
310316

311-
First packing script to one folder by PyInstaller::
312-
313-
$ pyinstaller foo.py
317+
.. versionchanged:: 8.5.4
314318

315-
It generates one bundle folder ``dist/foo``, and an executable file ``dist/foo/foo``, pass this executable to pyarmor::
319+
Before v8.5.4, it need more work, please check old version documentation (v8.5.3).
316320

317-
$ pyarmor gen -O obfdist --pack dist/foo/foo foo.py
321+
Packing script to one folder::
318322

319-
Like above section, ``dist/foo/foo`` will be repacked with obfuscated scripts.
323+
pyarmor gen --pack onefolder foo.py
320324

321-
Now run it::
325+
Run the final bundle::
322326

323-
$ dist/foo/foo
327+
dist/foo/foo
324328

325329
More information about pack feature, refer to :doc:`../topic/repack`
326330

src/cli/repack.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import sys
77
import tempfile
88

9-
from json import load as json_load
109
from importlib._bootstrap_external import _code_to_timestamp_pyc
1110
from subprocess import check_call, check_output, DEVNULL
1211

0 commit comments

Comments
 (0)