Change Logs

**Since v7.3.1, some features may be not available for old pyarmor
license. pyarmor will report “This license may be expired” when using those features**

Incompatible issues

  • Incompatible of the license.lic

    v7.0.1 v6.0.1

    The license file generated by these versions doesn’t work with the old obfuscated scripts. There are 2 solutions for this case, still generating the license file with old version pyarmor, or obfuscating the scripts again by new version pyarmor.

    However license.lic generated by old version still works. That is to say, even all the scripts are obfuscated by new version, you need not issue new license file to customers, because the previous license file still works.

  • Incompatible of the obfuscated scripts

    Generally obfuscate part of scripts by new version, then overwrite the old scripts obfuscated by other version, it still works.

    Except the following versions:


    The scripts are obfuscated by this version and later, can not mixed with the ones obfuscated by ealier version. All the scripts must be obfuscated again and replace the old runtime files with new ones.

8.0.1 (developing)

From PyArmor 8.0.1, there are some incompatible changes

  • SPP mode doesn’t work prior to PyArmor 8.0, please upgrade pyarmor to 8.0+ to use it. And it only works in arch x86_64 and aarch64, no plan to support new platforms for SPP mode. For other platforms, use BCC mode instead. BCC mode is an enhancement of SPP mode, and has schedule to support X86, armv7.
  • In previous versions, querying registration information by command pyarmor register will not work after 2023-12-31. It still works in PyArmor 8.0+

New big features:

  • Customize and localize runtime error messages
  • Introduce irreversible obfuscation mode BCC, it’s an enhancement of SPP mode.
  • Introduce irreversible obfuscation mode RFT, it could rename all the function/class/method/argument/variable.

Fixed bugs:

  • Fix bug (#908): –mix-str doesn’t work if there is encoding line
  • Fix spp mode bug: the decorators of nest function are ignored


In order to improve security and support Python 3.11, there are significant changes from Pyarmor 8.0, more information refer to


  • Fix bug: pyinstaller option –upx-dir doesn’t work in the command pack
  • Fix bug (#884): “insert one redundant line” doesn’t work in Python 3.10 for super mode


  • Fix bug(#882, #883): pack command fails when using pyinstaller option –onefile


  • Fix bug(#882): pack command fails when using pyinstaller option –onefile


  • Fix bug(#853): pack command fails when passing the –upx-dir flag to PyInstaller
  • Fix bug(#860): –exact flag doesn’t work in the option -x of pack command
  • Fix bug(#878): For pyinstaller 5.6.2, pack command fails with error win32ctypes.pywin32.pywintypes.error: (2, ‘LoadLibraryEx’, ‘The system cannot find the file specified’)


  • Fix bug(#814): –mix-str results in from __future__ import xxx error
  • Change core version to r52.6
  • Remove duplicated mac addresses when printing all mac addresses
  • Fix super mode crash bug in aarch64 platform
  • Change spp build library version to r4
  • Fix spp mode bug: RuntimeError: Init spp mode failed when function name starts with lambda_
  • Fix spp mode crash bugs


  • Change spp build library version to r3
  • Fix bug: ImportError: dynamic module does not define module export function (PyInit_pytransform_vax_xxxxxx)


  • For command obfuscate add option –mix-str to obfuscate the string value
  • For command config add option –mixin, only avaliable mixin is str now
  • Project add new attribute mixins to support option –mixin
  • Change core version to r51.5
  • Change spp build library version to r2
  • Fix spp mode crash bugs because of the same list/dict/set constants conflicts
  • Fix spp mode crash bugs because cellvars and freevars are freed even they are still used by other lambda/functions.


  • Fix spp mode bug (#758): from __future__ imports must occur at the beginning of the file
  • Fix spp mode bug (#760): ‘Set’ object has no attribute ‘ctx’
  • Fix spp mode bug (#760): redefinition of _listcomp_326_1
  • Fix spp mode bug: Can not import XXX from MMM
  • Fix spp mode bug: using PYTHONOPTIMIZE may results in sppmode fails.
  • Fix spp mode bugs regarding to with/lambda/comprehension


  • Fix command pack issue: if using –src in the option –xoptions, pyarmor raises excpetion “no entry script found”
  • Change core version and spp library version to r50.4
  • Support sppmode for Python3.7~3.10 in platforms: darwin.aarch64, linux.aarch64
  • Support sppmode for Python 3.10 in platforms: windows.x86_64, linux.x86_64, darwin.x86_64, darwin.aarch64, linux.aarch64
  • Fix sppmode bug: the result of inplace op for attribute is not right. For example, after self.a += 1, self.a isn’t increased in old version.
  • Fix sppmode bug: AnnAssign is ignored. For example, after x: int = 3, x still is undefined in old version.


  • Fix pack issue: pass duplicated extra options to PyInstaller


  • Fix inline option no-spp-mode issue


  • Fix encoding issue when generating entry script (#712)
  • Fix example scripts obfuscate-app.bat and obfuscate-pkg.bat bugs (#713)


  • Change core version to r49.3
  • Fix centos6 issue: GLIBC 2.14 not found
  • Fix python3.10 super mode crash issue (#686)
  • Support new platform musl.aarch64
  • Add new super mode darwin.aarch64 for Python 3.10


  • Refine register function.
  • In Darwin support option –platform darwin.aarch64,darwin.x86_64 to create universal runtime binary when obfuscationg the scripts.


  • Fix issue: pyarmor register doesn’t show register information for Python3
  • In Darwin codesign the runtime binary file to avoid the obfuscated scripts killed by Apple M1


  • Fix issue (#663): the merge script raises exception too many runtime files if the runtime files are generated by command runtime
  • Add new option –no-runtime for merge script helper.merge
  • Add new platform linux.x86.11.py310 to support super mode for Python 3.10
  • Do not load core library _pytransform for command register and download


  • Change core version to r48.2
  • Fix Apple Silcon crash issue: use darwin.aarch64.0 as default library
  • Add 2 super mode libraries: darwin.aarch64.8.py38, darwin.aarch64.8.py39


  • Fix typo in contact email when printing registration information.
  • Support pip config to pass extra option when building pyarmored wheel.


  • Fix issue(#644): build pyarmored wheel with the corresponding python tag and platform tag
  • Fix issue: build wheel failed



  • Fix issue (#639): failed to obfuscate Python 3.10 scripts for non super mode


  • Change contact email to


  • Check the conflicts of option --restrict 0 and --with-license
  • Fix issue (#628): super plus mode crashes if any function is patched
  • Fix link errors in documentation
  • Change core version to r47.1
  • Support Python 3.10. For super mode, now only 3 platforms: windows.x86_64, linux.x86_64, darwin.x86_64


  • In trial version it will raise RuntimeError if old core library is used to obfuscate the scripts
  • Check more for restrict mode 5


  • Fix bug: there is no error message to run pack command with common debug option -d


A big feature Super Plus Mode is introduced in this version, and the format of license file for obfuscated scripts is changed.

Because the trial version uses the old core libraries, so it doesn’t work with new license. When running the scripts which are obfuscated by trial version with option --platform or --advanced, it will raise exception:

Check license failed, Invalid input packet.
  • Fix issue (#584): failed to run pyarmor in Cygwin
  • Fix issue (#586): In linux combining options both –enable-suffix and –advanced 1 doesn’t work
  • Change core version to r46.20
  • Add sppmode, refer to Super Plus Mode
  • Change the format of license file for obfuscated scripts and the old core libraries (before r46.20) doesn’t work with new licenses.


  • Fix issue (#571): In Linux/Darwin super mode with –enable-suffix doesn’t work
  • Fix issue (#584): In Cygwin pyarmor doesn’t work


  • Fix issue (#557): Invalid platform name for VM mode
  • Change core version to r45.19
  • In Linux support to get the serial number of mmc/sd card
  • In Linux refine the code of getting default harddisk
  • Supprot to run obfuscated scripts by multiple Python versions, refer to Run Obfuscated Scripts By Different Python Versions
  • Fix Apple Silicon doesn’t work issue


  • Fix issue (#547): in MacOS the repack script fails if the executable is signed.
  • Add option –code-identity for repack script
  • Fix issue (#549): refine repack script to wait for the termination of objcopy
  • Change core version to r44.18
  • Fix issue: in super mode object.__del__ raises exception NameError: name ‘__armor_wrap__’ is not defined
  • Fix issue (#530): in non-super mode object.__del__ raises exception NameError: name ‘__armor_enter__’ is not defined. Note that for Python 3.7 and later, this issue still exists in non-super mode. Use super mode for these Python versions to solve this issue.
  • Add restrict mode 100+, refer to Restrict Mode
  • Check sys.PYARMOR_LICENSE for outer license, and refine outer license search policy. Refer to How to use outer license file
  • Fix issue (#539): runtime command generates wrong protection code for super mode
  • Fix issue (#550): memory leak of builtin function locals in super mode


  • Add option -e to set the entry script for helper.repack
  • The entension of entry script could be .pyw


  • Fix issue (#518): remove platform part from extension name for super mode, the final name is always or pytransform.pyd
  • Change core version to r43.17
  • Fix issue: the platform “android.aarch64” always raises exception Check license failed, Invalid input packet


  • Support environment variable PYARMOR_TIMEOUT to set the timeout of any network connection.
  • Fix issue (#503): repack complains of too many pytransform
  • Support platform isilon onefs, alias of freebsd
  • Print the version of Python in the console when running pyarmor sub-command


There is a big change in this version is that the trial version could not download the latest extra core libraries. Except the core libraries distributed with soure package, for trial version all the other core libraries will always use the ones same as v6.6.2 (tag: r41.15).

  • Change core version to r42.16
  • Remove platform data file index.json from source package
  • The trial version could not download the latest platform libraries, it always uses core version r41.15
  • Fix super mode for Python39-32 in Windows issue(#489): Dll load failed (The specified procedure could not be found)

Only fixed in purchased version * Improve the security of check_armored for super mode * Fix memory leak issue for core dynamic libraries


  • Improve the security of restrict mode and assert_armored for super mode
  • Add new api pytransform.check_armored for super mode, it could be used to check module/function/method
  • Build super mode core libraries with rpath dependent in MacOS
  • Fix Python3.9 pack issue for MacOS: check_lib_pytransform failed
  • Fix Apple Silicon platform issue: the binary libraries doesn’t work
  • Fix issue (#471): in super mode get_license_info can’t get the updated license information.


  • Fix issue (#429): the new license doesn’t work if replace the old license with it in enable-period-mode
  • Fix extension filenames conflict for multiple platforms in super mode
  • Fix issue (#442): the target platforms in the runtime settings is read as a list
  • Fix issue (#452): when enable suffix for super mode in Linux, the obfuscated scripts raise ImportError: dynamic module does not define module export function
  • Fix issue (#460): the obfuscated scripts crash if they’re obfucated by –advanced 2 and –obf-code 0
  • Add new platforms: android.x86, android.x86_64



  • Rename option --runtime-path to -rpath in command config
  • Fix issue (#403): the obfuscated scripts raise unexpected exception in Python 2.7 (non-super mode)
  • Add new platform centos6.x86_64.11.py27 for Python 2.7 built with UCS2 and platform glibc < 2.14
  • Add new command help to open online documentation in the web browser
  • Fix issue (#408): undefined symbol PyUnicodeUCS2_AsUTF8String in arm platforms for Python 2.7
  • Rename platform name darwin.arm64 to darwin.aarch64
  • Add new platform darwin.aarch64.3, darwin.aarch64.11.py38 and darwin.aarch64.11.py39 to support Apple Silicon
  • In project copy non .py files to output directly if they’re specified in the project manifest
  • Fix issue (#414): repack doesn’t patch the final bundle in some platforms
  • Fix issue (#415): when repacking an executable where the embedded PKG archive contains subdirectories, the repack script fails



  • Refine output message when checking registration information by command pyarmor register
  • Runtime function get_hd_info() accepts keyword parameters name to get hardware information of named device
  • Command hdinfo accepts optional parameter name
  • Command licenses could bind obfuscated scripts to named hard disk
  • Print pretty error message if checking license or loading core dynamic library fails when running non-super mode obfuscated scripts
  • Fix issue (#387): exception Function does not end with “):” is raised when obfuscating the scripts


  • The command register also could register any text file only if it includes registration code in one single line
  • Add new option –buy for command register, which used to open shopping cart of PyArmor: pyarmor register –buy


  • Fix issue: it raises exception to register a code by Python 2.7


  • Support super mode for Python3.9
  • Show deprecation warning for –advanced 1 and –advanced 3 if super mode is available, use –advanced 2 and –advanced 4 instead
  • Both registration code and file are supported by the command register


  • Fix issue (#355): the obfuscated script raises DeprecationWarning when getting user data from license file in super mode with Python3.8
  • Fix issue (#357): Python3.9 doesn’t work, the obfuscated scripts raise unknow opcode 53/88 and segmentation fault


  • Fix issue(#337): project can’t be configured with outer license
  • Fix issue(#342): in Windows command pack doesn’t work if the project isn’t in the same drive of entry script


  • Support binding multiple mac addresses in one machine by format <Mac1,Mac2,Mac3…> in Windows and Linux
  • For platform linux.x86_64 and linux.x86, the core libraries of super mode for Python2.7 are linked to usc4, the old ones are linked to ucs2
  • Fix pack command issue: outer license may not work in some cases
  • The platform linux.armv6 supports super mode


  • Fix bug: for big endian platform, it raises RuntimeError: Invalid extension, no data found when obfuscating scripts (#323)
  • Fix bug: when obfuscating some special scripts in super mode, it raises RuntimeError: Patch function “xxx” failed (#326)
  • Fix serial number of hard disk issue in Windows: the last character is missed in some special cases


  • Command obfuscate accepts multiple arguments as entry scripts
  • Fix restrict mode crash issue for Python3.5~3.8 in 32-bit Windows
  • Fix super mode issue: attempted relative import beyond top-level package
  • Improve security of restrict mode
  • For restrict mode 2, do not protect module attributes for performance
  • Add restrict mode 5 to protect globals in functions
  • Refine the documentation of restrict mode:
  • Fix platform centos6.x86_64 not found issue (#312)
  • On Linux for command licenses the option –bind-mac supports new format: IfName/MacAddress, for example, eth0/00:28:54:af:28


  • A big improvement for restrict mode: the plain script couldn’t visit any module attribute if this module is obfuscated by restrict mode 2, 3 or 4
  • Add option –runtime for command obfuscate, build
  • In command runtime, deprecate option –super-mode and –vm-mode, use –advanced instead.
  • Fix encoding issue: couldn’t get the right encoding if source encoding is in the second line
  • Refine example scripts


  • Fix pack issue: if pyi-makespec could not be found, it will complain of OSError: [WinError 2] The system cannot find the file specified.
  • Fix PYTHONOPTIMIZE=2 doesn’t work issue
  • Fix super mode issue: auto patch failed if there are multiple lines in function header
  • Fix command register issue: it could not show registration information even if register successfully. It’s introduced in v6.3.5.


  • Fix pack project issue: not all the scripts in the project are re-obfuscated when packing the project again.
  • Clean license.lic in the pyarmor package if option –home isn’t used


  • Fix option –home issue: the file license.lic in this path doesn’t work
  • Improve the security of core dynamic libraries


  • Fix sub-package could not import pytransform when it’s obfuscated by –bootstrap 3 in super mode
  • For Windows platform, add new modes –advanced 3 and –advanced 4 to enable vm protection. Refer to
  • The default value of option obf-mod is set to 2
  • Add new platform linux.mips64 and linux.mips64el
  • Fix super mode crash issue for linux.armv7 and linux.aarch32


  • Fix super mode crash issue for Python37/38 in Windows
  • Fix command pack issue: the obfuscation option –enable-suffix doesn’t work


  • Fix super mode crash issue for Coroutine functions
  • Fix super mode exception issue
  • Fix restrict mode 3/4 doesn’t work in some cases
  • Fix super mode will complain of insert one redundant line ‘[None, None]’ issue


From this version, only 2 runtime files are required for non-super mode:


Most of the algorithm are refined to improve the security.

  • Refine the algorithm to improve security and performance
  • Refine default cross protection code
  • Refine runtime files, remove license.lic and pytransform.key
  • Refine pack command
  • Refine the obfuscating process for cross platforms
  • Refine benchmark command, and new option –advanced Refer to
  • Add platform musl.mips32 for MIPS32 with musl-libc
  • Add common options –boot for special cross platform obfuscating
  • Rename platform names alpine.* to musl.*

Upgrade notes

The scripts are obfuscated by old version could not work with this version, they must be obfuscated again.


  • Fix cross platform bug: in Windows it may raise exception can’t open file ‘…Scriptspyarmor’: [Errno 2] No such file or directory
  • Fix super mode bug: in some cases super mode will raise exception unknown opcode


  • Fix arch ppc64le could not work issue
  • In pack command, clean build cache automatically before packing the obfuscated scripts


  • Fix a crash issue in Darwin platform
  • Fix super mode issue in Darwin: the obfuscated scripts report “image not found” (#256)
  • Document experiment feature: how to protect data file


  • Fix get_license_info issue: the value of CODE is blank


  • Add option –with-license in the command build
  • Fix pack issue: the option –with-license doesn’t work in super mode
  • If the code object couldn’t be obfuscated in advanced 2 (super mode), fix it automatically by inserting one redundant line [None, None] at the beginning of this code object
  • Ignore case when checking mac address if the license is bind to network card
  • Add key ISSUER in the return value of get_license_info


  • Fix pack issue for Mac in super mode: RuntimeError: unexpected
  • Fix pack issue for windows 32-bit system: the default license doesn’t work in other machines, it complains of License is not for this machine


  • Add common option --home, so PYARMOR_HOME can be set in the command line
  • Fix pack issue: pack command may not work with super mode


  • Fix advanced mode issue: advanced mode 1 doesn’t work in pyenv and some platforms
  • Fix issue(#244): when obfuscating the scripts for cross platform and only one platform specified, the obfuscated scripts raise unexpected protection error.


  • Fix issue(#244): when specify only one platform the obfuscated scripts raise exception:

    [Errno 2] No such file or directory: 'xxx/'
  • Super mode supports windows.x86, linux.x86, linux.aarch64, linux.aarch32, linux.armv7


In this version, super mode is introduced to improve the security. In this mode the structure of PyCode_Type is changed, and byte code or word code is mapped, it’s the highest security level in PyArmor. There is only one runtime file required, that is extension module pytransform, and the form of obfuscated scripts is unique, no so called Bootstrap Code which may make some users confused. All the obfuscated scripts would be like this

from pytransform import pyarmor
pyarmor(__name__, __file__, b'\x0a\x02...', 1)

It’s recommended to enable this mode in suitable cases. Now only the latest Python versions are supported:

  • Python 2.7
  • Python 3.7
  • Python 3.8

It may support Python 3.5, 3.6 later, but Python 3.0~3.4 is out of plan.

  • Add new option –obf-mode, –obf-code, –wrap-mode to command obfuscate
  • Add new value 2 for option –advanced to enable super mode, refer to Using Super Mode
  • Fix multiprocessing issue: ValueError: __mp_main__.__spec__ is None (#232)
  • The command runtime will generate default protection script
  • Add new option –cross-protection to command obfuscate to specify customized protection script
  • The default cross protection code will not be injected the entry script if –no-runtime is specified as obfuscating the scripts. In this case, use option –cross-protection to specify one protection script
  • Change the default capsule location from ~/ to ~/.pyarmor/
  • Add new functions get_user_data, assert_armored in runtime module pytransform
  • Document how to store runtime file license.lic to any location
  • Remove the trailing dot from harddisk serial number, it may impact the license verified.


  • Add external plugin script
  • Enhance the command licenses:
    • The final argument could be empty, for example, pyarmor licenses will generate a default license to licenses/pyarmor/license.lic
    • If the output is end with license.lic, it will not append any other path, just save it as it is. For example, pyarmor licenses -O dist/license.lic will save the final output to dist/license.lic
    • Add new option –fixed, and document how to use this option to improve the security
  • In command pack, the default license will be generated with –fixed to improve the security



  • Fix restrict mode 3 bug: the obfuscated script crashes or complains of this error: This function could not be called from the plain script (#219)
  • Fix bug: the obfuscated script raises unknown opcode error when the script is obfuscated by obf_code=2 if there is recursive function call
  • Fix command init and config bug: the entry script is set to . other than empty when passing --entry=""
  • Fix bug: the traceback will print very long line if the obfuscated script raises exception
  • Fix bug: in some special cases the obfuscated scripts which are obfuscated with --enable-suffix still conflict with other obfuscated packages
  • Refine the error message as violating restrict mode
  • The obfuscated script will raise exception RuntimeError other than quit directly when something is wrong Now it will print a pretty traceback to find where is the problem
  • When generating license.lic for the obfuscated scripts, the license version information will be embedded into the license file implicitly
  • Do not transfer exception type to PytransformError as pyarmor initializes failed

Upgrade notes:

The license file generated by this version doesn’t work with the old obfuscated scripts. There are 2 solutions for this case:

  • Still generating the license file with old version pyarmor
  • Or obfuscating the scrips again by new version pyarmor


  • Fix restrict mode 3 bug: the obfuscated function failed if it’s called from generator function even in the obfuscated script.
  • In pack command it will try to use the encoding coding: xxx in the first comment line of .spec file


  • Fix pack issue: it will raise UnicodeDecodeError when the source path includes non-ascii characters(#217)
  • Fix obfuscate issue for Python2: it will raise UnicodeDecodeError when the source path includes non-ascii characters
  • Refine pack command: it will print the output of PyInstaller to the console either



  • Change the plugin search policy, do not support enviorment variable PYARMOR_PLUGIN, but search folder plugins in the pyarmor package path.

  • Add a new path plugins in the package source, there are several common plugins. So it’s easy to check internet time by this way:

    pyarmor obfuscate --plugin check_ntp_time

    Before that both of these lines should be inserted into

    # {PyArmor Plugins}
    # PyArmor Plugin: check_ntp_time()
  • Fix pack bug: pyi-makespec: error: unrecognized arguments: -y if extra options are passed

  • Document command pack in details:



  • Add new option --enable-period-mode in the command licenses
  • When running the obfuscated scripts it will check license periodly (per hour) if the option --enable-period-mode is set in the license file


  • Fix bug: the command pyarmor runtime –platform alpine.x86_64 raises error (#201)
  • Fix bug: the platform linux.armv6 doesn’t work in Raspberry PI Zero W, rebuild the dynamic library with -march=armv6 -mfloat-abi=hard -marm


  • Python debugger and profile tool could work with the plain python scripts even if the obfuscated packages are imported. Note that the obfuscated scripts still couldn’t be traced.
  • Refine pack command, use pyi-makespec to generate .spec file
  • Fix advanced mode fails in some linux platforms
  • Support platform linux.armv6
  • Fix python38 issue: in the wrap mode the footer block isn’t executed


pyarmor-webui is published as a separated package, it has been removed from source package of pyarmor. Now it’s a full feature webui, and could be installed by pip install pyarmor-webui.

  • Support environment variable PYARMOR_HOME as one extra path to find the license.lic of pyarmor. Now the search order is:

    • In the package path of pyarmor
    • $PYARMOR_HOME/.pyarmor/license.lic
    • $HOME/.pyarmor/license.lic
    • $USERPROFILE/.pyarmor/license.lic (Only for Windows)
  • In command licenses if option output is set, do not append extra path licenses in the final output path

  • In command obfuscate with option –exact, all the scripts list in the command line will be taken as entry script.

  • The last argument in command pack could be a project path or .json file

  • Add new option --name in the command pack

  • Add new project attribute license_file, bootstrap_code

  • Add new option --with-license, --bootstrap in the command config

  • Add new option --bootstrap in the command obfuscate

  • The options --package-runtime doesn’t support 2 and 3, use --bootstrap=2 or --bootstrap=3 instead

  • For command licenses the generated license could be printed to stdout by setting the option --output to stdout


  • Fix cross platform issue for vs2015.x86 and vs2015.x86_64
  • In command config add option --advanced as alias of --advanced-mode


  • Fix issue: the obfuscated scripts will crash when importing the packages obfuscated with advanced mode by other registered pyarmor


In this version, the scripts could be obfuscated with option --enable-suffix, then the name of the runtime package and builtin functions will be unique. By this way the scripts obfuscated by different capsule could run in the same Python interpreter.

For example, the bootstrap code may like this with suffix _vax_000001:

from pytransform_vax_000001 import pyarmor_runtime

Refer to

  • Add option --enable-suffix in the commands obfuscate, config and runtime
  • Add option --with-license in the command pack
  • Fix issue: the executable file made by pack raises protection fault exception on MacOSX


  • Raise exception other than sys.exit(1) when pyarmor_runtime fails
  • Refine cross protection code to improve the security
  • Fix issue: advanced mode fails in some MacOSX machines with python2.7


  • Add platform data file index.json to source package
  • Refine core library for platform MacOSX


  • Fix issue: advanced mode doesn’t work in some MacOSX machines.
  • Fix issue: can’t get the serial number of SSD harddisk in MacOSX platform


  • Fix issue: the _pytransform.dll for windows.x86_64 is not latest


  • Fix issue: the option --exclude in command obfuscate could not exclude .py files
  • Refine command pack


  • Fix issue: check license failed if there is no environment variable HOME in linux platform
  • Add new value 3 for option --package-runtime, the bootstrap code will always use relative import with an extra leading dot
  • The command runtime also generates bootstrap script
  • Add option --inside in command runtime to generate bootstrap package pytransform_bootstrap
  • Document how to run unittest of obfuscated scripts, refer to


  • Move the license file of pyarmor from the install path of pyarmor package to user home path ~/.pyarmor
  • Refine error messages so that the users could solve most of problems by the hints.
  • Refine command pack, use hook to add the runtime files.
  • The command pack supports customized spec file, refer to
  • In runtime module pytransform, the functions may raise Exception instead of PytransformError in some cases.
  • In command register, add option --legency to store license.lic in the traditional way
  • Fix platform name issue: in some linux platforms the platform name may not be right


  • Fix new linux platform centos6.x86_64 issue: raise TypeError when run pyarmor twice.


  • Support new linux platform centos6.x86_64, arch is x86_64, glibc < 2.14
  • Do not print traceback if no option --debug specified as running pyarmor


  • When the obfuscated scripts raise exception, eliminate the very long line from traceback to make it clear


  • Fix issue: pyarmor load _pytransform.dll faild by 32-bit Python in 64-bit Windows.


  • Add option --update for command download to update all the downloaded dynamic libraries automatically
  • Fix issue: the obfuscated script raises unexpected exception when the license is expired



  • Fix issue: command obfuscate fails if the option --src is specifed


  • Refine pytransform to handle error message of core library
  • Refine command online help message
  • Sort the scripts being to obfuscated to fix some random errors (#143)
  • Raise exception other than call sys.exit if pyarmor is called from another Python script directly
  • In the function get_license_info of module pytransform
    • Change the value to None if there is no corresponding information
    • Change the key name expired to upper case EXPIRED


  • Fix plugin codec issue (#138): ‘gbk’ codec can’t decode byte 0x82 in position 590: illegal multibyte sequence
  • Project src may be relative path base on project path
  • Refine plugin and document it in details:
  • Add common option --debug for pyarmor to show more information in the console
  • Project commands, for examples build, cofig, the last argument supports any valid project configuration file


  • Add command runtime to generate runtime package separately
  • Add the first character as alias for command obfuscate, licenses, pack, init, config, build
  • Fix cross platform obfuscating scripts don’t work issue (#136). This bug should be exists from v5.6.0 to v5.7.0 Related target platforms armv5, android.aarch64, ppc64le, ios.arm64, freebsd, alpine, alpine.arm, poky-i586


There are 2 major changes in this version:

  1. The runtime files are saved in the separated folder pytransform as package:


Upgrade notes:

  • If you have generated new runtime file “license.lic”, it should be copied to dist/pytransform other than dist/

  • If you’d like to save the runtime files in the same folder with obfuscated scripts as before, obfuscating the scripts with option package-runtime like this:

    pyarmor obfuscate --package-runtime=0
    pyarmor build --package-runtime=0
  1. The bootstrap code must be in the obfuscated scripts, and it must be entry script as obfuscating.

Upgrade notes:

  • If you have inserted bootstrap code into the obfuscated script dist/ which is obfuscated but not as entry script manually. Do it by this command after v5.7.0:

    pyarmor obfuscate --no-runtime --exact
  • If you need insert bootstrap code into plain script, first obfuscate an empty script like this:

    echo "" >
    pyarmor obfuscate --no-runtime --exact

    Then import pytransform_bootstrap in the plain script.

Other changes:

  • Change default value of project attribute package_runtime from 0 to 1
  • Change default value of option --package-runtime from 0 to 1 in command obfuscate
  • Add option --no-runtime for command obfuscate
  • Add optioin --disable-restrict-mode for command licenses


  • Add option --package-runtime in command obfuscate, config and build
  • Add attribute package_runtime for project
  • Refine default cross protection code
  • Remove deprecated flag for option --src in command obfuscate
  • Fix help message errors in command obfuscate


  • Fix issue (#129): “Invalid input packet” on raspberry pi (armv7)
  • Add new obfuscation mode: obf_code == 2


  • Remove unused exported symbols from core libraries


  • Fix win32 issue: verify license failed in some cases
  • Refine core library to improve security


  • Fix segmentation fault issue for Python 3.8


  • Add option -x in command licenses to save extra data in the license file. It’s mainly used to extend license type.


  • Fix pyarmor-webui start issue in some cases: can’t import name ‘_project’


  • The command download will check the version of dynamic library to be sure it works with the current PyArmor.


In this version, new private capsule, which use 2048 bits RSA key to improve security for obfucated scripts, is introduced for purchased users. All the trial versions still use one same public capsule which use 1024 bits RSA keys. After purchasing PyArmor, a keyfile which includes license key and private capsule will be sent to customer by email.

For the previous purchased user, the old private capsules which are generated implicitly by PyArmor after registered PyArmor still work, but maybe not supported later. Contact if you’d like to use new private capsule.

The other changes:

  • Command register are refined according to new private capsule

Upgrade Note for Previous Users

There are 2 solutions:

  1. Still use old license code.

It’s recommanded that you have generated some customized “license.lic” for the obfuscated scrips and these “license.lic” files have been issued to your customers. If use new key file, all the previous “license.lic” does not work, you need generate new one and resend to your customers.

Actually the command pip install –upgrade pyarmor does not overwrite the purchased license code, you need not run command pyarmor register again. It should still work, you can check it by run pyarmor -v.

Or in any machine in which old version pyarmor is running, compress the following 2 files to one archive “”:

  • license.lic, which locates in the installed path of pyarmor
  •, which locates in the user HOME path

Then register this keyfile in the new version of pyarmor

pyarmor register
  1. Use new key file.

It’s recommanded that you have not yet issued any customized “license.lic” to your customers.

Forward the purchased email received from MyCommerce to, and the new key file will be sent to the registration email. If pyarmor license is purchased after 2017-10-10, no fee for this upgrading. Before 2017-10-10, please purchase a new license for latest pyarmor.


  • Fix webui bug: raise “name ‘output’ is not defined” as running packer


  • Add new restrict mode 2, 3 and 4 to improve security of the obfuscated scripts, refer to Restrict Mode
  • In command obfuscate, option --restrict supports new value 2, 3 and 4
  • In command config, option --disable-restrict-mode is deprecrated
  • In command config, add new option --restrict
  • In command obfuscate the last argument could be a directory


  • Win32 issue: the obfuscated scripts will print extra message.


  • Fix issue: the output path isn’t correct when building a package with multiple entries
  • Fix issue: the obfuscated scripts raise SystemError “unknown opcode” if advanced mode is enabled in some MacOS machines


  • Fix issue: it will raise error “Invalid input packet” to import 2 independent obfuscated packages in 64-bit Windows.


  • Fix bug of command pack: the obfuscated modules aren’t packed into the bundle if there is an attribute _code_cache in the a.pure


  • Fix bug: it could not obfuscate more than 32 functions in advanced mode even pyarmor isn’t trial version.
  • In command licenses, the output path of generated license file is truncated if the registration code is too long, and all the invalid characters for path are removed.


  • Fix issue: Warning: code object xxxx isn’t wrapped (#59)
  • Refine command download, fix some users could not download library file from
  • Introduce advanced mode for x86/x64 arch, it has some limitations in trial version
  • Add option --advanced for command obfuscate
  • Add new property advanced_mode for project

A new feature Advanced Mode is introduced in this version. In this mode the structure of PyCode_Type is changed a little to improve the security. And a hook also is injected into Python interpreter so that the modified code objects could run normally. Besides if some core Python C APIs are changed unexpectedly, the obfuscated scripts in advanced mode won’t work. Because this feature is highly depended on the machine instruction set, it’s only available for x86/x64 arch now. And pyarmor maybe makes mistake if Python interpreter is compiled by old gcc or some other C compiles. It’s welcome to report the issue if Python interpreter doesn’t work in advanced mode.

Take this into account, the advanced mode is disabled by default. In order to enable it, pass option --advanced to command obfuscate. But in next minor version, this mode may be enable by default.

Upgrade Notes:

Before upgrading, please estimate Python interpreter in product environments to be sure it works in advanced mode. Here is the guide

It is recommended to upgrade in the next minor version.



  • Enhancement: In Linux support to get the serial number of NVME harddisk
  • Fix issue: After run command register, pyarmor could not generate capsule if there is license.lic in the current path


  • Fix issue: In Linux could not get the serial number of SCSI harddisk
  • Fix issuse: In Windows the serial number is not right if the leading character is alpha number



  • Option --exclude can use multiple times in command obfuscate
  • Exclude build path automatically in command pack


  • New feature: do not obfuscate functions which name starts with lambda_
  • Fix issue: it will raise Protection Fault as packing obfuscated scripts to one file


  • Do not obfuscate lambda functions by default
  • Fix issue: local variable platname referenced before assignment


  • Add option --url for command download


  • Add integrity checks for the downloaded binaries (#85)


  • Fix issue: get wrong harddisk’s serial number for some special cases in Windows


  • Query harddisk’s serial number without administrator in Windows


  • Remove the leading and trailing whitespace of harddisk’s serial number


  • Fix non-ascii path issue in Windows


  • Fix bug: the bootstrap code isn’t inserted correctly if the path of entry script is absolute path.



  • The bootstrap code could run many times in same Python interpreter.
  • Remove extra . from the bootstrap code of as building project without runtime files.


  • Add command download used to download platform-dependent dynamic libraries
  • Keep shell line for obfuscated entry scripts if there is first line starts with #!
  • Fix issue: if entry script is not in the src path, bootstrap code will not be inserted.



  • Fix bug: if there is only one comment line in the script it will raise IndexError as obfuscating this script.



  • In the trial version of PyArmor, it will raise error as obfuscating the code object which size is greater than 32768 bytes.
  • Add option --plugin in command obfuscate
  • Add property plugins for Project, and add option --plugin in command config
  • Change default build path for command pack, and do not remove it after command finished.


  • Fix segmentation fault issue for python3.5 and before: run too big obfuscated code object (>65536 bytes) will crash (#67)
  • Fix issue: missing bootstrap code for command pack (#68)
  • Fix issue: the output script is same as original script if obfuscating scripts with option --exact


  • Fix issue: pyarmor -v complains not enough arguments for format string


  • In command obfuscate add new options --exclude, --exact, --no-bootstrap, --no-cross-protection.
  • In command obfuscate deprecate the options --src, --entry, --cross-protection.
  • In command licenses deprecate the option --bind-file.


  • Fix issue: raise codec exception as obfuscating the script of utf-8 with BOM
  • Change the default path to user home for command capsule
  • Disable restrict mode by default as obfuscating special script
  • Refine log message


  • Fix issue: raise IndexError if output path is ‘.’ as building project
  • For Python3 convert error message from bytes to string as checking license failed
  • Refine version information


  • Fix arm64 issue: verify rsa key failed when running the obufscated scripts(#63)
  • Support ios (arm64) and ppc64le for linux


  • Refine error message when checking license failed
  • Fix issue: protection code raises ImportError in the package file __init.py__


  • Improve the security of dynamic library.


  • Fix issue: in restrict mode the bootstrap code in will raise exception.
  • Add option --cross-protection in command obfuscate


  • Use global capsule as default capsule for project, other than creating new one for each project
  • Add option --obf-code, --obf-mod, --wrap-mode, --cross-protection in command config
  • Add new attributes for project: obf_code, obf_mod, wrap_mode, cross_protection
  • Deprecrated project attributes obf_code_mode, obf_module_mode, use obf_code, obf_mod, wrap_mode instead
  • Change the behaviours of restrict mode, refer to
  • Change option --restrict in command obfuscate and licenses
  • Remove option --no-restrict in command obfuscate
  • Remove option --clone in command init


  • Improve the security of PyArmor self


  • Refine the procedure of encrypt script
  • Reform module
  • Fix issue: it will raise exception if no entry script when obfuscating scripts
  • Fix issue: ‘gbk’ codec can’t decode byte 0xa1 in position 28 (#51)
  • Add option --upgrade for command capsule
  • Merge runtime files pyshield.key, pyshield.lic and product.key into pytransform.key

Upgrade notes

The capsule created in this version will include a new file pytransform.key which is a replacement for 3 old runtime files: pyshield.key, pyshield.lic and product.key.

The old capsule which created in the earlier version still works, it stills use the old runtime files. But it’s recommended to upgrade the old capsule to new version. Just run this command:

pyarmor capsule --upgrade

All the license files generated for obfuscated scripts by old capsule still work, but all the scripts need to be obfuscated again to take new capsule effects.


  • Add extra code to protect dynamic library _pytransform when obfuscating entry script
  • Fix compling error when obfuscating scripts in windows for Python 26/30/31 (newline issue)



  • Fix get_expired_days issue, remove decorator dllmethod
  • Refine output message of pyarmor -v


  • Add option -q, --silent, suppress all normal output when running any PyArmor command
  • Refine runtime error message, make it clear and more helpful
  • Add new function get_hd_info in module pytransform to get hardware information
  • Remove function get_hd_sn from module pytransform, use get_hd_info instead
  • Remove useless function version_info, get_trial_days from module pytransform
  • Remove attribute lib_filename from module pytransform, use _pytransform._name instead
  • Add document
  • Refine document



Thanks to GNU lightning, from this version, the core routines are protected by JIT technicals. That is to say, there is no binary code in static file for core routines, they’re generated in runtime.

Besides, the pre-built dynamic library for linux arm32/64 are packed into the source package.

Fixed issues:

  • The module multiprocessing starts new process failed in obfuscated script:

    AttributeError: ‘__main__’ object has no attribute ‘f’


  • Fix backslash issue when running pack command with PyInstaller
  • When PyArmor fails, if sys.flags.debug is not set, only print error message, no traceback printed


  • Add option --options for command pack
  • For Python 3, there is no new line in the output when pack command fails


  • Fix license issue in 64-bit embedded platform


  • Fix crash issue for special code object in Python 3.6


  • Fix stack overflow issue


  • Refine platform name to search dynamic library _pytransform


  • Print the exact message when checking license failed to run obfuscated scripts.



  • Fix #41: can not find dynamic library _pytransform


  • Add anti-debug code for dynamic library _pytransform


  • Change default capsule to user home other than the source path of pyarmor


This patch mainly changes webui, make it simple more:

  • WebUI : remove source field in tab Obfuscate, and remove ipv4 field in tab Licenses
  • WebUI Packer: remove setup script, add output path, only support PyInstaller


  • Support Py2Installer by a simple way
  • For command obfuscate, get default src and entry from first argument, --src is not required.
  • Set no restrict mode as default for new project and command obfuscate, licenses


  • Pack obfuscated scripts by command pack

In this version, introduces a new command pack used to pack obfuscated scripts with py2exe and cx_Freeze. Once the setup script of py2exe or cx_Freeze can bundle clear python scripts, pack could pack obfuscated scripts by single command: pyarmor pack –type cx_Freeze /path/to/src/

  • Pack obfuscated scripts by WebUI packer

WebUI is well reformed, simple and easy to use.


  • Fix start pyarmor issue for pip install in Python 2


  • Fix issue: missing file in wheel


  • Fix pip install issue in MacOS
  • Refine sample scripts to make workaround for py2exe/cx_Freeze simple


  • Fix typos in examples
  • Fix bugs in sample scripts


In this version, there are three significant changes:

[Simplified WebUI]( [Clear Examples](src/examples/, quickly understand the most features of Pyarmor [Sample Shell Scripts](src/examples), template scripts to obfuscate python source files

  • Simply webui, easy to use, only input one filed to obfuscate python scripts
  • The runtime files will be always saved in the same path with obfuscated scripts
  • Add shell scripts obfuscate-app, obfuscate-pkg, build-with-project, build-for-2exe in src/examples, so that users can quickly obfuscate their python scripts by these template scripts.
  • If entry script is, change the first line of bootstrap code from pytransform import pyarmor runtime to from .pytransform import pyarmor runtime
  • Rewrite examples/, make it clear and easy to understand
  • Do not generate entry scripts if only runtime files are generated
  • Remove choice package for option --type in command init, only pkg reserved.


  • Fix pyarmor-webui can not start issue
  • Fix runtime-path issue in webui
  • Rename platform name macosx_intel to macosx_x86_64 (#36)


  • Fix webui import error.


  • Add option --recursive for command obfuscate


  • Rewrite project long description.


  • Fix Python3 issue for get_license_info


  • Add function get_license_info in to show license information


  • Fix import main from pyarmor issue


  • Add command capsule
  • Find default capsule in the current path other than --src in command obfuscate
  • Fix pip install issue #30


  • Rename to
  • Rename to
  • Add option --capsule, -disable-restrict-mode and --output for command licenses


  • Add option --capsule for command init, config and obfuscate
  • Deprecate option --clone for command init, use --capsule instead
  • Fix sys.settrace and sys.setprofile issues for auto-wrap mode


  • Fix segmentation fault issues for asyncio, typing modules


  • Add documentation for examples (examples/


  • Fix windows 10 issue: access violation reading 0x000001ED00000000


  • Fix the generated license bind to fixed machine in webui is not correct
  • Fix extra output path issue in webui


  • Show registration code when printing version information


  • Rewrite long description of package in pypi


  • Fix issue: __file__ is not really path in main code of module when import obfuscated module


  • Replace option --disable-restrict-mode with --no-restrict in command obfuscate
  • Add option --title in command config
  • Change the output path of entry scripts when entry scripts belong to package
  • Refine document and


  • Add option --type for command init
  • Refine document and


This version introduces a new way auto-wrap to protect python code when it’s imported by outer scripts.

Refer to [Mechanism Without Restrict Mode](src/

  • Add new mode wrap for --obf-code-mode
  • Remove func.__refcalls__ in __wraparmor__
  • Add new project attribute is_package
  • Add option --is-package in command config
  • Add option --disable-restrict-mode in command obfuscate
  • Reset build_time when project configuration is changed
  • Change output path when is_package is set in command build
  • Change default value of project when find in comand init
  • Project attribute entry supports absolute path


  • Fix shared code object issue in __wraparmor__


  • Clear frame as long as tb is not Py_None when call __wraparmor__
  • Generator will not be obfucated in __wraparmor__


  • Fix bug: the frame.f_locals still can be accessed in callback function


  • The frame.f_locals of wrapper and wrapped function will return an empty dictionary once __wraparmor__ is called.


  • The frame.f_locals of wrapper and wrapped function return an empty dictionary, all the other frames still return original value.


  • The frame.f_locals of all frames will always return an empty dictionary to protect runtime data.
  • Add extra argument tb when call __wraparmor__ in decorator wraparmor, pass None if no exception.


  • Do not touch frame.f_locals when raise exception, let decorator wraparmor to control everything.


  • Fix issue: option --disable-restrict-mode doesn’t work in command licenses
  • Remove freevar func from frame.f_locals when raise exception in decorator wraparmor


  • Change module filename to <frozen modname> in traceback, set attribute __file__ to real filename when running obfuscated scripts.


  • Try to access original func_code out of decorator wraparmor is forbidden.


  • Add option --output for command build, it will override the value in project configuration file.
  • Fix issue: defalut project output path isn’t relative to project path.
  • Remove extra file “product.key” after obfuscating scripts.


  • Remove dotted name from filename in traceback, if it’s not a package.


  • Strip __init__ from filename in traceback, replace it with package name.


  • Remove brackets from filename in traceback, and add dotted prefix.


  • Change filename in traceback to <frozen [modname]>, other than original filename


  • Fix issue #12: module attribute __file__ is filename in build machine other than filename in target machine.
  • Builtins function __wraparmor__ only can be used in the decorator wraparmor


  • Fix issue #11: use decorator “wraparmor” to obfuscate func_code as soon as function returns.
  • Document usage of decorator “wraparmor”, refer to src/


  • Fix issue #8 (Linux): option –manifest broken in shell script


  • Add option “Restrict Mode” in web ui
  • Document restrict mode in details (


  • Introduce restrict mode to avoid obfuscated scripts observed from no obfuscated scripts
  • Add option –disable-restrict-mode for command “config”


  • Support pip install pyarmor


  • Fix Python3.6 issue: can not run obfuscated scripts, because it uses a 16-bit wordcode instead of bytecode
  • Fix Python3.7 issue: it adds a flag in pyc header
  • Fix option –obf-module-mode=none failed
  • Add option –clone for command “init”
  • Generate runtime files to separate path “runtimes” when project runtime-path is set
  • Add advanced usages in user-guide


  • Fix issue: raise exception when project entry isn’t obfuscated


  • Add webui to manage project


  • Fix README.rst format error.
  • Add title attribute to project
  • Print new command help when option is -h, –help


Pyarmor v3.4 introduces a group new commands. For a simple package, use command obfuscate to obfuscate scripts directly. For complicated package, use Project to manage obfuscated scripts.

Project includes 2 files, one configure file and one project capsule. Use manifest template string, same as of Python Distutils, to specify the files to be obfuscated.

To create a project, use command init, use command info to show project information. config to update project settings, and build to obfuscate the scripts in the project.

Other commands, benchmark to metric performance, hdinfo to show hardware information, so that command licenses can generate license bind to fixed machine.

All the old commands capsule, encrypt, license are deprecated, and will be removed from v4.

A new document [src/](src/ is written for this new version.


  • Remove unused files in distribute package


In this version, new obfuscate mode 7 and 8 are introduced. The main difference is that obfuscated script now is a normal python file (.py) other than compiled script (.pyc), so it can be used as common way.

Refer to

  • Introduce new mode: 7, 8
  • Change default mode from 3 to 8
  • Change to test new mode
  • Update webapp and tutorial
  • Update usage
  • Fix issue of py2exe, now py2exe can work with python scripts obfuscated by pyarmor
  • Fix issue of odoo, now odoo can load python modules obfuscated by pyarmor


  • Fix issue: the traceback of an exception contains the name “<pytransform>” instead of the correct module name
  • Fix issue: All the constant, co_names include function name, variable name etc still are in clear text. Refer to


From this version, a new obfuscation mode is introduced. By this way, no import hooker, no setprofile, no settrace required. The performance of running or importing obfuscation python scripts has been remarkably improved. It’s significant for Pyarmor.

  • Use this new mode as default way to obfuscate python scripts.
  • Add new script “” to check performance in target machine: python
  • Change option “–bind-disk” in command “license”, now it must be have a value


  • Add option “–bind-mac”, “–bind-ip”, “–bind-domain” for command “license”
  • Command “hdinfo” show more information(serial number of hdd, mac address, ip address, domain name)
  • Fix the issue of dev name of hdd for Banana Pi


  • Fix serial number of harddisk doesn’t work in mac osx.


  • Support MACOS


  • Fix issue: load _pytransfrom failed in linux x86_64 by subprocess.Popen
  • Fix typo in error messge when load _pytransfrom failed.


A web gui interface is introduced as Pyarmor WebApp, and support

  • In encrypt command, save encrypted scripts with same file structure of source.
  • Add a web gui interface for pyarmor.
  • Support to list files for command encrypt
  • Add option –manifest, file list will be written here
  • DO NOT support absolute path in file list for command encrypt
  • Option –main support format “”


  • Refine decrypted mechanism to improve performance
  • Fix unknown opcode problem in recursion call
  • Fix wrapper scripts generated by -m in command ‘encrypt’ doesn’t work
  • Raise ImportError other than PytransformError when import encrypted module failed


In this version, introduce 2 extra encrypt modes to improve performance of encrypted scripts.

  • Fix issue when import encrypted package
  • Add encrypted mode 2 and 3 to improve performance
  • Refine module pyimcore to improve performance


It’s a milestone for Pyarmor, from this version, use ctypes import dynamic library of core functions, other than by python extensions which need to be built with every python version.

Besides, in this version, a big change which make Pyarmor could avoid soure script got by c debugger.

  • Use ctypes load core library other than python extentions which need built for each python version.
  • “__main__” block not running in encrypted script.
  • Avoid source code got by c debugger.
  • Change default outoupt path to “build” in command “encrypt”
  • Change option “–bind” to “–bind-disk” in command “license”
  • Document usages in details


  • Fix encrypted scripts don’t work in multi-thread framework (Django).


  • Add option ‘-i’ for command ‘encrypt’ so that the encrypted scripts will be saved in the original path.


  • Verbose tracelog when checking license in trace mode.
  • In license command, change default output filename to “license.lic.txt”.
  • Read bind file when generate license in binary mode other than text mode.


  • Fix problem when script has line “from __future__ import with_statement”
  • Fix error when running pyarmor by 32bit python on the 64bits Windows.
  • (Experimental)Support darwin_15-x86_64 platform by adding extensions/


  • License file can mix expire-date with fix file or fix key.
  • Fix log error: not enough arguments for format string


  • License file can bind to ssh private key file or any other fixed file.


  • Change default extension “.pyx” to “.pye”, because it confilcted with CPython.
  • Custom the extension of encrypted scripts by os environment variable: PYARMOR_EXTRA_CHAR
  • Block the hole by which to get bytescode of functions.


  • The trial license will never be expired (But in trial version, the key used to encrypt scripts is fixed).


  • Refine the document


  • Fix error data in examples of wizard


  • Implement Run function in the GUI wizard
  • Make license works in trial version


  • Add a GUI wizard
  • Add examples to show how to use pyarmor


  • Fix syntax-error when run/import encrypted scripts in linux x86_64


  • Support armv6


  • Add option ‘–path’ for command ‘encrypt’
  • Support script list in the file for command ‘encrypt’
  • Fix issue to encrypt an empty file result in pytransform crash


  • Add option ‘–expired-date’ for command ‘license’
  • Fix undefined ‘tfm_desc’ for arm-linux
  • Enhance security level of scripts


  • Print exactaly message when pyarmor couldn’t load extension “pytransform”
  • Fix problem “version ‘GLIBC_2.14’ not found”
  • Generate “license.lic” which could be bind to fixed machine.


  • Add missing extensions for linux x86_64.


  • Add command “licene” to generate more “license.lic” by project capsule.


  • Add information for using registration code


  • Add option –with-extension to support cross-platform publish.
  • Implement command “capsule” and add option –with-capsule so that we can encrypt scripts with same capsule.
  • Remove command “convert” and option “-K/–key”


  • Encrypt pyshield.lic when distributing source code.


  • Enhance encrypt algorithm to protect source code.
  • Developer can use custom key/iv to encrypt source code
  • Compiled scripts (.pyc, .pyo) could be encrypted by pyshield
  • Extension modules (.dll, .so, .pyd) could be encrypted by pyshield