# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['nibbler', 'nibbler.extension']

package_data = \
{'': ['*']}

install_requires = \
['black>=18.9b0,<19.0', 'uncompyle6>=3.2,<4.0']

setup_kwargs = {
    'name': 'nibbler',
    'version': '0.1.3',
    'description': 'Runtime bytecode optimizer.',
    'long_description': '<p align="center">\n<img src="https://user-images.githubusercontent.com/9287847/52054870-21754d80-255e-11e9-9169-843316357763.png" width="600px" alt="nibbler"/>\n</p>\n\n---\n[![Python 3.7](https://img.shields.io/badge/python-3.7-%233572A5.svg)](https://docs.python.org/3/whatsnew/3.7.html)\n[![PyPI version](https://badge.fury.io/py/nibbler.svg)](https://badge.fury.io/py/nibbler)\n[![Not production ready](https://img.shields.io/badge/production%20ready-hell%20no-red.svg)]()\n[![Travis status](https://travis-ci.org/PhilipTrauner/nibbler.svg?branch=master)](https://travis-ci.org/PhilipTrauner/nibbler)\n\n**nibbler** is a runtime bytecode optimizer.\n\nIt explores the concept of using existing Python syntax features such as *type annotations* and *decorators* to **speed up** code execution by running additional bytecode optimization passes that make use of runtime context provided through these means.\n\n## Optimization passes\n* [`inline`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/inline.py)  \n\tInlines parameter-less calls to functions that are decorated with `@nibbler.inline`.\n* [`constantize_globals`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/constantize_globals.py)  \n\tCopies the value of globals that were marked constant (with a `Constant` type annotation or with the `@nibbler.constant` decorator) into the `co_consts` tuple of functions that would normally have to access the global namespace, which speeds up variable access. This also applies to builtins (`any`, `all`, `print`, ...).\n* [`precompute_conditionals`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/precompute_conditionals.py)  \n\tStrips out conditionals that test constants which the peephole optimizer doesn\'t pick up on.\n* [`global_to_fast`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/global_to_fast.py)  \n\tTransforms global variable loads to local variable loads if a local variable with the same name exists (mostly a cleanup pass for [`inline`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/inline.py))\n* [`peephole`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/peephole.py)  \n\tInvokes the [Python peephole optimizer](https://github.com/python/cpython/blob/master/Python/peephole.c) with additional context.\n\n\n## Usage\n```python\nfrom typing import Iterable\n\nfrom nibbler import Constant, Nibbler\n\nDEBUG: Constant[bool] = False\n\nnibbler = Nibbler(globals())\n\n\n@nibbler.inline\ndef square(number: int, base: int) -> int:\n    result = number ** base\n    return result\n\n\n@nibbler.nibble\ndef sequential_square(numbers: Iterable[int]) -> int:\n    product = 0\n    base = 2\n    for number in numbers:\n        square()\n\n        if DEBUG:\n            print(result)\n\n        product += result\n\n    print(f"Result: {product}")\n\n    return product\n\n\nsequential_square(range(4))\n```\n<p align="center"><b>\xe2\x86\x93</b></p>\n\n```\nResult: 14\n```\n\nExamining the function bytecode reveals which optimizations **nibbler** has performed:\n```\n  2           0 LOAD_CONST               1 (0)\n              2 STORE_FAST               1 (product)\n\n  3           4 LOAD_CONST               2 (2)\n              6 STORE_FAST               2 (base)\n\n  4           8 SETUP_LOOP              28 (to 38)\n             10 LOAD_FAST                0 (numbers)\n             12 GET_ITER\n        >>   14 FOR_ITER                20 (to 36)\n             16 STORE_FAST               3 (number)\n\n  5          18 LOAD_FAST                3 (number)\n             20 LOAD_FAST                2 (base)\n             22 BINARY_POWER\n             24 STORE_FAST               4 (result)\n\n  6          26 LOAD_FAST                1 (product)\n             28 LOAD_FAST                4 (result)\n             30 INPLACE_ADD\n             32 STORE_FAST               1 (product)\n             34 JUMP_ABSOLUTE           14\n        >>   36 POP_BLOCK\n\n  8     >>   38 LOAD_CONST               5 (<built-in function print>)\n             40 LOAD_CONST               3 (\'Result: \')\n             42 LOAD_FAST                1 (product)\n             44 FORMAT_VALUE             0\n             46 BUILD_STRING             2\n             48 CALL_FUNCTION            1\n             50 POP_TOP\n\n  9          52 LOAD_FAST                1 (product)\n             54 RETURN_VALUE\n```\n\n* The `square` function was inlined ([`inline`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/inline.py)) (18-24)\n* Conditional (`if DEBUG`) was stripped out, because `DEBUG` was declared a constant ([`precompute_conditionals`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/precompute_conditionals.py)) (26)\n* The `print` function was promoted to a function-level constant ([`constantize_globals`](https://github.com/PhilipTrauner/nibbler/blob/master/nibbler/extension/constantize_globals.py)) (38)\n\n## Installation\n```sh\npip3 install nibbler\n```\n\n## FAQ\n\n* Is this production ready?  \n\tHell no.\n* Why is it called **nibbler**?  \n\t\xc2\xaf\\\\\\_(\xe3\x83\x84)\\_/\xc2\xaf\n\n## Prior Art\n* [fatoptimizer](https://github.com/vstinner/fatoptimizer)\n* [PEP 510](https://www.python.org/dev/peps/pep-0510/)\n* [PEP 511](https://www.python.org/dev/peps/pep-0511/)\n* [falcon](https://github.com/rjpower/falcon)\n',
    'author': 'Philip Trauner',
    'author_email': 'philip.trauner@arztpraxis.io',
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
