├── .gitignore
├── LICENSE
├── README.md
├── demo.ipynb
├── demo_inplace.gif
├── demo_newcell.gif
├── ipyfuturize.py
├── requirements.txt
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[cod]
2 | .ipynb_checkpoints
3 |
4 | # C extensions
5 | *.so
6 |
7 | # Packages
8 | *.egg
9 | *.egg-info
10 | dist
11 | build
12 | eggs
13 | parts
14 | bin
15 | var
16 | sdist
17 | develop-eggs
18 | .installed.cfg
19 | lib
20 | lib64
21 |
22 | # Installer logs
23 | pip-log.txt
24 |
25 | # Unit test / coverage reports
26 | .coverage
27 | .tox
28 | nosetests.xml
29 | htmlcov
30 |
31 | # Translations
32 | *.mo
33 |
34 | # Mr Developer
35 | .mr.developer.cfg
36 | .project
37 | .pydevproject
38 |
39 | # Complexity
40 | output/*.html
41 | output/*/index.html
42 |
43 | # Sphinx
44 | docs/_build
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Douglas La Rocca
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ipyfuturize
2 |
3 | A cell magic for [futurize](http://python-future.org/futurize.html) (based on [2to3](https://docs.python.org/2/library/2to3.html))
4 |
5 | ## usage & demo
6 |
7 | Ctrl-Enter overwrites the active cell (Ctrl-z will undo)
8 |
9 | 
10 |
11 | Ctrl-Shift-Enter writes to a new cell
12 |
13 | 
14 |
15 | Line arguments are passed directly to the `futurize` script.
16 |
17 | Executing `%%futurize?` will show the same help info as `!futurize --help`.
18 |
19 | If you're using a virtual environment it will attempt to find the `futurize` script at `$VIRTUAL_ENV/bin/futurize`, otherwise it assumes the one you want to use is in `$PATH`.
20 |
21 | No windows support.
22 |
23 | ## install
24 |
25 | ```
26 | %install_ext https://raw.github.com/douglas-larocca/ipyfuturize/master/ipyfuturize.py
27 | ```
28 |
29 | then
30 |
31 | ```
32 | %load_ext ipyfuturize
33 | ```
34 |
35 | and use with
36 |
37 | ```
38 | %%futurize
39 | ```
40 |
41 | Also see the [demo notebook](demo.ipynb)
42 |
--------------------------------------------------------------------------------
/demo.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# ipyfuturize\n",
8 | "\n",
9 | "A cell magic for [futurize](http://python-future.org/futurize.html) (based on [2to3](https://docs.python.org/2/library/2to3.html))"
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "collapsed": true
17 | },
18 | "outputs": [],
19 | "source": [
20 | "%install_ext https://raw.github.com/douglas-larocca/ipyfuturize/master/ipyfuturize.py"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": 1,
26 | "metadata": {
27 | "collapsed": true
28 | },
29 | "outputs": [],
30 | "source": [
31 | "%load_ext ipyfuturize"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 6,
37 | "metadata": {
38 | "collapsed": false
39 | },
40 | "outputs": [
41 | {
42 | "name": "stdout",
43 | "output_type": "stream",
44 | "text": [
45 | "Usage: futurize [options] file|dir ...\r\n",
46 | "\r\n",
47 | "Options:\r\n",
48 | " -h, --help show this help message and exit\r\n",
49 | " -V, --version Report the version number of futurize\r\n",
50 | " -a, --all-imports Add all __future__ and future imports to each module\r\n",
51 | " -1, --stage1 Modernize Python 2 code only; no compatibility with Python 3 (or dependency on\r\n",
52 | " ``future``)\r\n",
53 | " -2, --stage2 Take modernized (stage1) code and add a dependency on ``future`` to provide Py3\r\n",
54 | " compatibility.\r\n",
55 | " -0, --both-stages Apply both stages 1 and 2\r\n",
56 | " -u, --unicode-literals\r\n",
57 | " Add ``from __future__ import unicode_literals`` to implicitly convert all\r\n",
58 | " unadorned string literals '' into unicode strings\r\n",
59 | " -f FIX, --fix=FIX Each FIX specifies a transformation; default: all. Either use '-f division -f\r\n",
60 | " metaclass' etc. or use the fully-qualified module name: '-f\r\n",
61 | " lib2to3.fixes.fix_types -f libfuturize.fixes.fix_unicode_keep_u'\r\n",
62 | " -j PROCESSES, --processes=PROCESSES\r\n",
63 | " Run 2to3 concurrently\r\n",
64 | " -x NOFIX, --nofix=NOFIX\r\n",
65 | " Prevent a fixer from being run.\r\n",
66 | " -l, --list-fixes List available transformations\r\n",
67 | " -p, --print-function Modify the grammar so that print() is a function\r\n",
68 | " -v, --verbose More verbose logging\r\n",
69 | " --no-diffs Don't show diffs of the refactoring\r\n",
70 | " -w, --write Write back modified files\r\n",
71 | " -n, --nobackups Don't write backups for modified files.\r\n",
72 | " -o OUTPUT_DIR, --output-dir=OUTPUT_DIR\r\n",
73 | " Put output files in this directory instead of overwriting the input files.\r\n",
74 | " Requires -n. For Python >= 2.7 only.\r\n",
75 | " -W, --write-unchanged-files\r\n",
76 | " Also write files even if no changes were required (useful with --output-dir);\r\n",
77 | " implies -w.\r\n",
78 | " --add-suffix=ADD_SUFFIX\r\n",
79 | " Append this string to all output filenames. Requires -n if non-empty. For Python\r\n",
80 | " >= 2.7 only.ex: --add-suffix='3' will generate .py3 files.\r\n"
81 | ]
82 | }
83 | ],
84 | "source": [
85 | "%%futurize?"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "Example from [http://python-future.org/quickstart.html#to-convert-existing-python-2-code](http://python-future.org/quickstart.html#to-convert-existing-python-2-code)"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 2,
98 | "metadata": {
99 | "collapsed": false
100 | },
101 | "outputs": [
102 | {
103 | "data": {
104 | "application/javascript": [
105 | "\n",
106 | " var cell = IPython.notebook.get_selected_cell();\n",
107 | " var content = \"from __future__ import print_function\\nfrom future import standard_library\\nstandard_library.install_aliases()\\nfrom builtins import next\\nfrom builtins import object\\nimport configparser # Py2 module name\\n\\nclass Upper(object):\\n def __init__(self, iterable):\\n self._iter = iter(iterable)\\n def __next__(self): # Py2-style iterator interface\\n return next(self._iter).upper()\\n def __iter__(self):\\n return self\\n\\nitr = Upper('hello')\\nprint(next(itr), end=' ')\\nfor letter in itr:\\n print(letter, end=' ') # Py2-style print statement\";\n",
108 | " \n",
109 | " cell.code_mirror.setValue(content);\n",
110 | " "
111 | ],
112 | "text/plain": [
113 | ""
114 | ]
115 | },
116 | "metadata": {},
117 | "output_type": "display_data"
118 | }
119 | ],
120 | "source": [
121 | "%%futurize\n",
122 | "import ConfigParser # Py2 module name\n",
123 | "\n",
124 | "class Upper(object):\n",
125 | " def __init__(self, iterable):\n",
126 | " self._iter = iter(iterable)\n",
127 | " def next(self): # Py2-style iterator interface\n",
128 | " return next(self._iter).upper()\n",
129 | " def __iter__(self):\n",
130 | " return self\n",
131 | "\n",
132 | "itr = Upper('hello')\n",
133 | "print next(itr),\n",
134 | "for letter in itr:\n",
135 | " print letter, # Py2-style print statement"
136 | ]
137 | }
138 | ],
139 | "metadata": {
140 | "kernelspec": {
141 | "display_name": "Python 3",
142 | "language": "python",
143 | "name": "python3"
144 | },
145 | "language_info": {
146 | "codemirror_mode": {
147 | "name": "ipython",
148 | "version": 3
149 | },
150 | "file_extension": ".py",
151 | "mimetype": "text/x-python",
152 | "name": "python",
153 | "nbconvert_exporter": "python",
154 | "pygments_lexer": "ipython3",
155 | "version": "3.6.0a0"
156 | }
157 | },
158 | "nbformat": 4,
159 | "nbformat_minor": 0
160 | }
161 |
--------------------------------------------------------------------------------
/demo_inplace.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglas-larocca/ipyfuturize/b0ee523cfa973ac7022653e659a6794be80a930e/demo_inplace.gif
--------------------------------------------------------------------------------
/demo_newcell.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglas-larocca/ipyfuturize/b0ee523cfa973ac7022653e659a6794be80a930e/demo_newcell.gif
--------------------------------------------------------------------------------
/ipyfuturize.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import shlex
4 | from tempfile import NamedTemporaryFile
5 | from datetime import datetime
6 | from IPython.core.display import Javascript
7 | from IPython.core.magic import Magics, magics_class, cell_magic, line_magic
8 | from IPython.core.magics import DisplayMagics
9 | from subprocess import Popen, PIPE
10 |
11 |
12 | class CellInject(object):
13 | def __init__(self, *args, **kwargs):
14 | pass
15 | def __call__(self, cell, extrajs=''):
16 | if not isinstance(cell, str):
17 | cell = json.dumps(cell)
18 | if not cell.startswith('"'):
19 | cell = json.dumps(cell)
20 | cell = '''
21 | var cell = IPython.notebook.get_selected_cell();
22 | var content = {0};
23 | {extrajs}
24 | cell.code_mirror.setValue(content);
25 | '''.format(cell, extrajs=extrajs)
26 | DisplayMagics().javascript('', cell)
27 |
28 |
29 | @magics_class
30 | class IPythonFuturize(Magics):
31 |
32 | def __init__(self, *args, **kwargs):
33 | super().__init__(*args, **kwargs)
34 |
35 | @line_magic('futurize')
36 | def ipython_futurize(self, line):
37 | raise NotImplementedError()
38 |
39 | @cell_magic('futurize')
40 | def ipython_futurize(self, line, cell):
41 | """
42 | Usage: futurize [options] file|dir ...
43 |
44 | Options:
45 | -h, --help show this help message and exit
46 | -V, --version Report the version number of futurize
47 | -a, --all-imports Add all __future__ and future imports to
48 | each module
49 | -1, --stage1 Modernize Python 2 code only; no compatibility
50 | with Python 3 (or dependency on ``future``)
51 | -2, --stage2 Take modernized (stage1) code and add a dependency
52 | on ``future`` to provide Py3 compatibility.
53 | -0, --both-stages Apply both stages 1 and 2
54 | -u, --unicode-literals
55 | Add ``from __future__ import unicode_literals``
56 | to implicitly convert all unadorned string literals
57 | '' into unicode strings
58 | -f FIX, --fix=FIX Each FIX specifies a transformation; default: all.
59 | Either use '-f division -f metaclass' etc. or use the
60 | fully-qualified module name: '-f lib2to3.fixes.fix_types
61 | -f libfuturize.fixes.fix_unicode_keep_u'
62 | -j PROCESSES, --processes=PROCESSES
63 | Run 2to3 concurrently
64 | -x NOFIX, --nofix=NOFIX
65 | Prevent a fixer from being run.
66 | -l, --list-fixes List available transformations
67 | -p, --print-function Modify the grammar so that print() is a function
68 | -v, --verbose More verbose logging
69 | --no-diffs Don't show diffs of the refactoring
70 | -w, --write Write back modified files
71 | -n, --nobackups Don't write backups for modified files.
72 | -o OUTPUT_DIR, --output-dir=OUTPUT_DIR
73 | Put output files in this directory instead of overwriting the
74 | input files. Requires -n. For Python >= 2.7 only.
75 | -W, --write-unchanged-files
76 | Also write files even if no changes were required
77 | (useful with --output-dir); implies -w.
78 | --add-suffix=ADD_SUFFIX
79 | Append this string to all output filenames. Requires -n
80 | if non-empty. For Python >= 2.7 only.ex: --add-suffix='3'
81 | will generate .py3 files.
82 | """
83 |
84 | try:
85 | futurize = os.path.join(os.environ['VIRTUAL_ENV'], 'bin/futurize')
86 | except KeyError:
87 | futurize = 'futurize'
88 |
89 | with NamedTemporaryFile(delete=False, suffix='.py') as f:
90 | f.write(cell.encode('utf-8'))
91 | filename = f.name
92 |
93 | args = shlex.split(' '.join((futurize, '-w', line, filename)))
94 |
95 | p = Popen(args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
96 | out, err = p.communicate()
97 |
98 | with open(filename, 'r') as f:
99 | rf = f.read()
100 |
101 | inj = CellInject()
102 | inj(rf)
103 |
104 | def load_ipython_extension(ip):
105 | """Load the extension in IPython."""
106 | ip.register_magics(IPythonFuturize)
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ipython>=3.0.0-b1
2 | future>=0.14.3
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | try:
6 | from setuptools import setup
7 | except ImportError:
8 | from distutils.core import setup
9 |
10 |
11 | with open('README.md') as readme_file:
12 | readme = readme_file.read()
13 |
14 | requirements = [
15 | 'ipython>=3.0.0-b1',
16 | 'future>=0.14.3',
17 | ]
18 |
19 | setup(
20 | name='ipyfuturize',
21 | version='0.0.1',
22 | description="%%futurize magic for ipython",
23 | long_description=readme,
24 | author="Douglas La Rocca",
25 | author_email='doug@larocca.io',
26 | url='https://github.com/douglas-larocca/ipyfuturize',
27 | install_requires=requirements,
28 | license="MIT",
29 | keywords='futurize 2to3 ipython magic',
30 | classifiers=[
31 | 'Development Status :: 2 - Pre-Alpha',
32 | 'Intended Audience :: Developers',
33 | 'Natural Language :: English',
34 | "Programming Language :: Python :: 2",
35 | 'Programming Language :: Python :: 2.6',
36 | 'Programming Language :: Python :: 2.7',
37 | 'Programming Language :: Python :: 3',
38 | 'Programming Language :: Python :: 3.3',
39 | 'Programming Language :: Python :: 3.4',
40 | 'Framework :: IPython',
41 | ],
42 | py_modules=['ipyfuturize'],
43 | )
44 |
--------------------------------------------------------------------------------