pyminifier.py - The main module for minifying, obfuscating, and compressing Python code

Python Minifier: Reduces the size of (minifies) Python code for use on embedded platforms.

Performs the following:

  • Removes docstrings.

  • Removes comments.

  • Minimizes code indentation.

  • Removes trailing commas.

  • Joins multiline pairs of parentheses, braces, and brackets (and removes extraneous whitespace within).

  • Joins disjointed strings like, (“some” “disjointed” “string”) into single strings: (‘’’some disjointed string’’’)

  • Preserves shebangs and encoding info (e.g. “# – coding: utf-8 –“).

  • Optionally, produces a bzip2 or gzip-compressed self-extracting python script containing the minified source for ultimate minification. Added in version 1.4

  • Optionally, obfuscates the code using the shortest possible combination of letters and numbers for one or all of class names, function/method names, and variables. The options are --obfuscate or -O to obfuscate everything, --obfuscate-variables, --obfuscate-functions, and --obfuscate-classes to obfuscate things individually (say, if you wanted to keep your module usable by external programs). Added in version 2.0

  • Optionally, a value may be specified via –replacement-length to set the minimum length of random strings that are used to replace identifier names when obfuscating.

  • Optionally, you may specify --nonlatin to use funky unicode characters when obfuscating. WARNING: This will result in some seriously hard-to-read code! Tip: Combine this setting with higher --replacement-length values to make the output even wackier. Added in version 2.0

  • Pyminifier can now minify/obfuscate an arbitrary number of Python scripts in one go. For example, pyminifier -O *.py will minify and obfuscate all files in the current directory ending in .py. To prevent issues with using differentiated obfuscated identifiers across multiple files, pyminifier will keep track of what replaces what via a lookup table to ensure foo_module.whatever is gets the same replacement across all source files. Added in version 2.0

  • Optionally, creates an executable zip archive (pyz) containing the minified/obfuscated source script and all implicit (local path) imported modules. This mechanism automatically figures out which source files to include in the .pyz archive by analyzing the script passed to pyminifier on the command line (listing all the modules your script uses is unnecessary). This is also the ultimate in minification/compression besting both the gzip and bzip2 compression mechanisms with the disadvantage that .pyz files cannot be imported into other Python scripts. Added in version 2.0

Just how much space can be saved by pyminifier? Here’s a comparison:

  • The pyminifier3 (as of version 2.1) source (all 7 files) takes up about 106k.

  • Performing basic minification on all pyminifier3 source files reduces that to ~104k.

  • Minification plus obfuscation provides a further reduction to 92k.

  • Minification plus the base64-encoded gzip trick (–gzip) reduces it to 76k.

  • Minification plus gzip compression plus obfuscation is also 76k (demonstrating that obfuscation makes no difference when compression algorithms are used).

  • Using the –pyz option on pyminifier.py creates a ~14k .pyz file that includes all the aforementioned files.

Various examples and edge cases are sprinkled throughout the pyminifier code so that it can be tested by minifying itself. The way to test is thus:

$ python __main__.py __main__.py > minified_pyminifier.py
$ python minified_pyminifier.py __main__.py > this_should_be_identical.py
$ diff minified_pyminifier.py this_should_be_identical.py
$

If you get an error executing minified_pyminifier.py or this_should_be_identical.py isn’t identical to minified_pyminifier.py then something is broken.

Note

The test functions below are meaningless. They only serve as test/edge cases for testing pyminifier3.

pyminifier.is_iterable(obj)[source]

Returns True if obj is iterable but not if obj is a string, bytes, or a bytearray.

pyminifier.pyminify(options, files)[source]

Given an options object (from optparse.OptionParser or similar), performs minification and/or obfuscation on the given files (any iterable containing file paths) based on said options.

All accepted options can be listed by running python __main__.py -h or examining the __init__.main() function.

class pyminifier.test_class[source]

Testing indented decorators

pyminifier.test_decorator(f)[source]

Decorator that does nothing

pyminifier.test_empty_functions()[source]

This is a test function. This should be replaced with “def test_empty_functions(): pass”

pyminifier.test_function()[source]

This function encapsulates the edge cases to prevent them from invading the global namespace.

pyminifier.test_reduce_operators()[source]

Test the case where an operator such as an open paren starts a line