Skip to content

Commit f79e000

Browse files
committed
(∩`-´)⊃━☆゚.*・。゚
1 parent 29197bb commit f79e000

File tree

7 files changed

+261
-0
lines changed

7 files changed

+261
-0
lines changed

.editorconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; This file is for unifying the coding style for different editors and IDEs.
2+
; More information at http://EditorConfig.org
3+
4+
; Editors and IDEs plugins:
5+
; — SublimeText — https://github.com/sindresorhus/editorconfig-sublime
6+
; — Vim — https://github.com/editorconfig/editorconfig-vim
7+
; — JetBrains IDEs — https://github.com/editorconfig/editorconfig-jetbrains
8+
9+
root = true
10+
11+
[*]
12+
charset = utf-8
13+
end_of_line = lf
14+
insert_final_newline = true
15+
trim_trailing_whitespace = true
16+
17+
[*.{py,md,ini}]
18+
indent_style = space
19+
indent_size = 4

.gitignore

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
### Python ###
2+
# Byte-compiled / optimized / DLL files
3+
__pycache__/
4+
*.py[cod]
5+
*$py.class
6+
7+
# C extensions
8+
*.so
9+
10+
# Distribution / packaging
11+
.Python
12+
env/
13+
build/
14+
develop-eggs/
15+
dist/
16+
downloads/
17+
eggs/
18+
.eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*,cover
47+
.hypothesis/
48+
49+
# Translations
50+
*.mo
51+
*.pot
52+
53+
# Sphinx documentation
54+
docs/_build/
55+
56+
# PyBuilder
57+
target/
58+
59+
60+
### Django ###
61+
*.log
62+
*.pot
63+
*.pyc
64+
__pycache__/
65+
local_settings.py
66+
db.sqlite3
67+
media
68+
69+
70+
### SublimeText ###
71+
# cache files for sublime text
72+
*.tmlanguage.cache
73+
*.tmPreferences.cache
74+
*.stTheme.cache
75+
76+
# workspace files are user-specific
77+
*.sublime-workspace
78+
79+
# project files should be checked into the repository, unless a significant
80+
# proportion of contributors will probably not be using SublimeText
81+
*.sublime-project
82+
83+
# sftp configuration file
84+
sftp-config.json
85+
86+
87+
### Other ###

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include MANIFEST.in
2+
include *.md
3+
global-exclude __pycache__
4+
global-exclude *.py[co]

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# asyncio-ipython-magic [![Requirements Status](https://requires.io/github/Gr1N/asyncio-ipython-magic/requirements.svg?branch=master)](https://requires.io/github/Gr1N/asyncio-ipython-magic/requirements/?branch=master) [![PyPI](https://img.shields.io/pypi/v/asyncio-ipython-magic.svg)](https://pypi.python.org/pypi/asyncio-ipython-magic) [![Supported Python versions](https://img.shields.io/pypi/pyversions/asyncio-ipython-magic.svg)](https://pypi.python.org/pypi/asyncio-ipython-magic)
2+
3+
An extension for [IPython](https://ipython.org) that help to run AsyncIO code in your interactive session.
4+
5+
Based on [Gist](https://gist.github.com/takluyver/b9663b08ac9a4472afa6).
6+
7+
## Installation
8+
9+
Install `asyncio-ipython-magic` using [pip](http://www.pip-installer.org/):
10+
11+
$ pip install asyncio-ipython-magic
12+
13+
...or directly from the repository using the `%install_ext` magic command:
14+
15+
$ In[1]: %install_ext https://raw.githubusercontent.com/Gr1N/asyncio-ipython-magic/master/asynciomagic.py
16+
17+
Enjoy!
18+
19+
## Usage
20+
21+
In [1]: %load_ext asynciomagic
22+
23+
In [2]: import asyncio
24+
25+
In [3]: import time
26+
27+
In [4]: async def foo():
28+
...: i = 0
29+
...: while i < 3:
30+
...: print('time =', time.time())
31+
...: i += 1
32+
...: await asyncio.sleep(2)
33+
...:
34+
35+
In [5]: %%asyncio
36+
...: await foo()
37+
...:
38+
time = 1478985421.307329
39+
time = 1478985423.309606
40+
time = 1478985425.31514
41+
42+
In [6]:
43+
44+
## Testing
45+
46+
It just works, I hope.
47+
48+
## License
49+
50+
*asyncio-ipython-magic* is licensed under the MIT license. See the license file for details.

asynciomagic.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import ast
4+
from ast import Call, Attribute, Name, Load
5+
import asyncio as _asyncio
6+
7+
from IPython.core.magic import Magics, magics_class, cell_magic
8+
from IPython.utils.text import indent
9+
10+
11+
class RewriteAwait(ast.NodeTransformer):
12+
def visit_Await(self, node):
13+
self.generic_visit(node)
14+
15+
new = Call(
16+
func=Attribute(
17+
value=Call(
18+
func=Attribute(
19+
value=Name(
20+
id='_asyncio',
21+
ctx=Load()
22+
),
23+
attr='get_event_loop',
24+
ctx=Load()),
25+
args=[],
26+
keywords=[]
27+
),
28+
attr='run_until_complete',
29+
ctx=Load()
30+
),
31+
args=[node.value],
32+
keywords=[]
33+
)
34+
35+
return ast.copy_location(new, node)
36+
37+
def visit_AsyncFunctionDef(self, node):
38+
# Don't transform awaits inside an 'async def' function
39+
return node
40+
41+
def visit_Return(self, node):
42+
raise SyntaxError('Return outside function definition')
43+
44+
45+
@magics_class
46+
class AsyncIOMagics(Magics):
47+
@cell_magic
48+
def asyncio(self, line, cell):
49+
coro_wrapper = 'async def __f():\n{cell}'.format(cell=indent(cell))
50+
coro_wrapper = ast.parse(coro_wrapper)
51+
coro_wrapper = coro_wrapper.body[0].body
52+
53+
nodes = [RewriteAwait().visit(node) for node in coro_wrapper]
54+
module = ast.Module(nodes)
55+
ast.fix_missing_locations(module)
56+
57+
coro = compile(module, filename='<asynciomagic>', mode='exec')
58+
59+
self.shell.ex(coro)
60+
61+
62+
def load_ipython_extension(ipython):
63+
ipython.user_global_ns['_asyncio'] = _asyncio
64+
ipython.register_magics(AsyncIOMagics)
65+
66+
67+
def unload_ipython_extension(ipython):
68+
ipython.user_global_ns.pop('_asyncio', None)

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[bdist_wheel]
2+
universal = 1

setup.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from setuptools import setup
4+
5+
6+
setup(
7+
name='asyncio-ipython-magic',
8+
version='0.0.1',
9+
description='An extension for IPython that help to run AsyncIO code in '
10+
'your interactive session.',
11+
author='Nikita Grishko',
12+
author_email='[email protected]',
13+
url='https://github.com/Gr1N/asyncio-ipython-magic',
14+
py_modules=(
15+
'asynciomagic',
16+
),
17+
install_requires=(
18+
'ipython',
19+
),
20+
include_package_data=True,
21+
classifiers=(
22+
'Development Status :: 3 - Alpha',
23+
'Framework :: IPython',
24+
'Intended Audience :: Developers',
25+
'Operating System :: OS Independent',
26+
'Programming Language :: Python',
27+
'Programming Language :: Python :: 3',
28+
'Programming Language :: Python :: 3.5',
29+
'Topic :: Software Development :: Libraries :: Python Modules',
30+
),
31+
)

0 commit comments

Comments
 (0)