Skip to content

Commit

Permalink
🎉 Initial commit
Browse files Browse the repository at this point in the history
This is the inital commit of python-minifier. It currently supports
Python 2.6-2.7 and Python 3.3-3.5.

Includes a basic API and pyminify command.

Further work is required to add support for Python 3.6+ before release.
  • Loading branch information
dflook committed Jun 18, 2018
0 parents commit dff78b4
Show file tree
Hide file tree
Showing 18 changed files with 2,729 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .circleci/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM fedora

# CircleCI required tools
RUN dnf install -y \
git \
openssh \
tar \
gzip \
gpg \
ca-certificates

# Python versions
RUN dnf install -y \
python26 \
python27 \
python33 \
python34 \
python35 \
python36 \
python37 \
pypy \
pypy3

WORKDIR /tmp/work
ENTRYPOINT ["/bin/bash"]
53 changes: 53 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: 2
jobs:
test:
docker:
- image: danielflook/python-minifier-build
steps:
- checkout

- run:
name: Set version statically
command: |
VERSION=$(python setup.py --version)
sed -i "s/setup_requires=.*/version='$VERSION',/; s/use_scm_version=.*//" setup.py
- run:
name: tox
command: |
pip install -r requirements-tox.txt
tox -e py27,py34,py35,pypy
publish:
docker:
- image: danielflook/python-minifier-build
steps:
- checkout

- run:
name: Set version statically
command: |
VERSION=$(python setup.py --version)
sed -i "s/setup_requires=.*/version='$VERSION',/; s/use_scm_version=.*//" setup.py
- run:
name: Add signing key
command: |
echo $SIGNING_KEY | base64 -d > private.key
gpg --import private.key
- run:
name: sdist
command: |
pip3 install --upgrade setuptools wheel twine pip
python3 setup.py sdist bdist_wheel
twine upload --sign dist/*
workflows:
version: 2
build:
jobs:
- test
- publish:
requires:
- test
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.tox/
.idea/
__pycache__/
*.py[cod]
dist/
downloads/
eggs/
.eggs/
wheels/
*.egg-info/
*.egg
venv/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Daniel Flook

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include *.txt
include LICENSE
include tox.ini
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Python Minifier

Transforms Python source code into it's most compact representation.

python-minifier supports Python 2.6 to 2.7 and Python 3.3 to 3.5..

As an example, the following python source:

```python
import ast

from python_minifier.miniprinter import MiniPrinter
from python_minifier.ast_compare import AstCompare

class UnstableMinification(Exception):
def __init__(self, original, minified, exception):
self.original = original
self.minified = minified
self.exception = exception

def __str__(self):
return str(self.exception)

def minify(source):

code = ast.parse(source)
minifier = MiniPrinter()

minifier.visit(code)

try:
# Check that the minified code is identical to the original
minified_code = ast.parse(minifier.code)
comparer = AstCompare()
comparer.compare(code, minified_code)
except Exception as exception:
raise UnstableMinification(source, minifier.code, exception)

return minifier.code
```

Becomes:

```python
import ast
from python_minifier.miniprinter import MiniPrinter
from python_minifier.ast_compare import AstCompare
class UnstableMinification(Exception):
def __init__(self,original,minified,exception):
self.original=original;self.minified=minified;self.exception=exception
def __str__(self):return str(self.exception)
def minify(source):
code=ast.parse(source);minifier=MiniPrinter();minifier.visit(code)
try:
minified_code=ast.parse(minifier.code);comparer=AstCompare();comparer.compare(code,minified_code)
except Exception as exception:
raise UnstableMinification(source,minifier.code,exception)
return minifier.code
```

## Why?

AWS Cloudformation templates may have AWS lambda function source code embedded in them, but only if the function is less
than 4KiB. I wrote this package so I could write python normally and still embed the module in a template.

## Installation

To install python-minifier use pip:

```bash
$ pip install python-minifier
```

Note that python-minifier depends on the python interpreter for parsing source code,
so install using a version of python appropriate for your source.

python-minifier runs with and can minify code written for Python 2.6 to 2.7 and Python 3.3 to 3.5.

## Usage

To minify a source file, and write the minified module to stdout:

```bash
$ pyminify hello.py
```

There is also an API. The same example would look like:

```python
import python_minifier

with open('hello.py') as f:
print(python_minifier.minify(f.read()))
```

## License

Available under the MIT License. Full text is in the [LICENSE](LICENSE) file.

Copyright 2018 Daniel Flook
2 changes: 2 additions & 0 deletions requirements-tox.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tox
virtualenv<16.0.0
52 changes: 52 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os.path
from setuptools import setup, find_packages

readme_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')
with open(readme_path) as f:
long_desc = f.read()

setup(
name='python_minifier',
description='Transform Python source code into it\'s most compact representation',
author='Daniel Flook',
author_email='[email protected]',
url='https://github.com/dflook/python-minifier',
license='MIT',
project_urls={
'Issues': 'https://github.com/dflook/python-minifier/issues',
'Say Thanks!': 'https://saythanks.io/to/dflook',
},
keywords='minify minifier',

use_scm_version=True,
package_dir={'': 'src'},
packages=find_packages('src'),
long_description=long_desc,
long_description_content_type='text/markdown',

python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <3.6',
setup_requires=['setuptools_scm'],

classifiers=[
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Intended Audience :: Developers',
'Topic :: Software Development'
],

entry_points = {
'console_scripts': ['pyminify=python_minifier.__main__:main']
},

zip_safe=True
)
63 changes: 63 additions & 0 deletions src/python_minifier/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import ast

from python_minifier.ast_compare import AstComparer, CompareError
from python_minifier.miniprinter import MiniPrinter


class UnstableMinification(RuntimeError):
def __init__(self, exception, source, minified):
self.exception = exception
self.source = source
self.minified = minified

def __str__(self):
return 'Minification was unstable! Please create an issue at https://github.com/dflook/python-minifier/issues'


def minify(source, filename=None):
"""
Minify a python module
With the default arguments an exact representation of the input source is returned.
:param str source: The python module to minify
:param str filename: The original source filename if known
:rtype: str
"""

filename = filename or 'python_minifer.minify source'

# This will raise if the source file can't be parsed
module = ast.parse(source, filename)

printer = MiniPrinter()
printer(module)

try:
minified_module = ast.parse(printer.code, 'python_minifier.minify output')
except SyntaxError as syntax_error:
raise UnstableMinification(syntax_error, source, printer.code)

try:
comparer = AstComparer()
comparer.compare(module, minified_module)
except CompareError as compare_error:
raise UnstableMinification(compare_error, source, printer.code)

return printer.code


def awslambda(source, filename=None):
"""
Minify a python module for use as an AWS Lambda function
This returns a string suitable for embedding in a cloudformation template.
:param str source: The python module to minify
:param str filename: The original source filename if known
:rtype: str
"""

return minify(source, filename)
18 changes: 18 additions & 0 deletions src/python_minifier/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from __future__ import print_function

import sys

from python_minifier import minify


def main():
if len(sys.argv) < 2:
print('Usage: pyminify <PATH>')
exit(-1)

with open(sys.argv[1], 'rb') as f:
print(minify(f.read()))


if __name__ == '__main__':
main()
Loading

0 comments on commit dff78b4

Please sign in to comment.