We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
cython_pyximport reload broken in python3
python3.3 notebook, tested in 0.13.1 but the code looks the same in HEAD:

%%cython_pyximport foo
def f(x):
    return 4.0*x

execute twice and you get 

```
/usr/lib/python3/dist-packages/IPython/extensions/cythonmagic.py in cython_pyximport(self, line, cell)
     99         if module_name in self._reloads:
    100             module = self._reloads[module_name]
--> 101             reload(module)
    102         else:
    103             __import__(module_name)

NameError: global name 'reload' is not defined
```

imp.reload should be used here


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `IPython/extensions/cythonmagic.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 =====================
4 Cython related magics
5 =====================
6 
7 Usage
8 =====
9 
10 ``%%cython``
11 
12 {CYTHON_DOC}
13 
14 ``%%cython_inline``
15 
16 {CYTHON_INLINE_DOC}
17 
18 ``%%cython_pyximport``
19 
20 {CYTHON_PYXIMPORT_DOC}
21 
22 Author:
23 * Brian Granger
24 
25 Parts of this code were taken from Cython.inline.
26 """
27 #-----------------------------------------------------------------------------
28 # Copyright (C) 2010-2011, IPython Development Team.
29 #
30 # Distributed under the terms of the Modified BSD License.
31 #
32 # The full license is in the file COPYING.txt, distributed with this software.
33 #-----------------------------------------------------------------------------
34 
35 from __future__ import print_function
36 
37 import imp
38 import io
39 import os
40 import re
41 import sys
42 import time
43 
44 try:
45     import hashlib
46 except ImportError:
47     import md5 as hashlib
48 
49 from distutils.core import Distribution, Extension
50 from distutils.command.build_ext import build_ext
51 
52 from IPython.core import display
53 from IPython.core import magic_arguments
54 from IPython.core.magic import Magics, magics_class, cell_magic
55 from IPython.testing.skipdoctest import skip_doctest
56 from IPython.utils import py3compat
57 
58 import Cython
59 from Cython.Compiler.Errors import CompileError
60 from Cython.Build.Dependencies import cythonize
61 
62 
63 @magics_class
64 class CythonMagics(Magics):
65 
66     def __init__(self, shell):
67         super(CythonMagics,self).__init__(shell)
68         self._reloads = {}
69         self._code_cache = {}
70 
71     def _import_all(self, module):
72         for k,v in module.__dict__.items():
73             if not k.startswith('__'):
74                 self.shell.push({k:v})
75 
76     @cell_magic
77     def cython_inline(self, line, cell):
78         """Compile and run a Cython code cell using Cython.inline.
79 
80         This magic simply passes the body of the cell to Cython.inline
81         and returns the result. If the variables `a` and `b` are defined
82         in the user's namespace, here is a simple example that returns
83         their sum::
84 
85             %%cython_inline
86             return a+b
87 
88         For most purposes, we recommend the usage of the `%%cython` magic.
89         """
90         locs = self.shell.user_global_ns
91         globs = self.shell.user_ns
92         return Cython.inline(cell, locals=locs, globals=globs)
93 
94     @cell_magic
95     def cython_pyximport(self, line, cell):
96         """Compile and import a Cython code cell using pyximport.
97 
98         The contents of the cell are written to a `.pyx` file in the current
99         working directory, which is then imported using `pyximport`. This
100         magic requires a module name to be passed::
101 
102             %%cython_pyximport modulename
103             def f(x):
104                 return 2.0*x
105 
106         The compiled module is then imported and all of its symbols are
107         injected into the user's namespace. For most purposes, we recommend
108         the usage of the `%%cython` magic.
109         """
110         module_name = line.strip()
111         if not module_name:
112             raise ValueError('module name must be given')
113         fname = module_name + '.pyx'
114         with io.open(fname, 'w', encoding='utf-8') as f:
115             f.write(cell)
116         if 'pyximport' not in sys.modules:
117             import pyximport
118             pyximport.install(reload_support=True)
119         if module_name in self._reloads:
120             module = self._reloads[module_name]
121             reload(module)
122         else:
123             __import__(module_name)
124             module = sys.modules[module_name]
125             self._reloads[module_name] = module
126         self._import_all(module)
127 
128     @magic_arguments.magic_arguments()
129     @magic_arguments.argument(
130         '-c', '--compile-args', action='append', default=[],
131         help="Extra flags to pass to compiler via the `extra_compile_args` "
132              "Extension flag (can be specified  multiple times)."
133     )
134     @magic_arguments.argument(
135         '--link-args', action='append', default=[],
136         help="Extra flags to pass to linker via the `extra_link_args` "
137              "Extension flag (can be specified  multiple times)."
138     )
139     @magic_arguments.argument(
140         '-l', '--lib', action='append', default=[],
141         help="Add a library to link the extension against (can be specified "
142              "multiple times)."
143     )
144     @magic_arguments.argument(
145         '-L', dest='library_dirs', metavar='dir', action='append', default=[],
146         help="Add a path to the list of libary directories (can be specified "
147              "multiple times)."
148     )
149     @magic_arguments.argument(
150         '-I', '--include', action='append', default=[],
151         help="Add a path to the list of include directories (can be specified "
152              "multiple times)."
153     )
154     @magic_arguments.argument(
155         '-+', '--cplus', action='store_true', default=False,
156         help="Output a C++ rather than C file."
157     )
158     @magic_arguments.argument(
159         '-f', '--force', action='store_true', default=False,
160         help="Force the compilation of a new module, even if the source has been "
161              "previously compiled."
162     )
163     @magic_arguments.argument(
164         '-a', '--annotate', action='store_true', default=False,
165         help="Produce a colorized HTML version of the source."
166     )
167     @cell_magic
168     def cython(self, line, cell):
169         """Compile and import everything from a Cython code cell.
170 
171         The contents of the cell are written to a `.pyx` file in the
172         directory `IPYTHONDIR/cython` using a filename with the hash of the
173         code. This file is then cythonized and compiled. The resulting module
174         is imported and all of its symbols are injected into the user's
175         namespace. The usage is similar to that of `%%cython_pyximport` but
176         you don't have to pass a module name::
177 
178             %%cython
179             def f(x):
180                 return 2.0*x
181 
182         To compile OpenMP codes, pass the required  `--compile-args`
183         and `--link-args`.  For example with gcc::
184 
185             %%cython --compile-args=-fopenmp --link-args=-fopenmp
186             ...
187         """
188         args = magic_arguments.parse_argstring(self.cython, line)
189         code = cell if cell.endswith('\n') else cell+'\n'
190         lib_dir = os.path.join(self.shell.ipython_dir, 'cython')
191         quiet = True
192         key = code, sys.version_info, sys.executable, Cython.__version__
193 
194         if not os.path.exists(lib_dir):
195             os.makedirs(lib_dir)
196 
197         if args.force:
198             # Force a new module name by adding the current time to the
199             # key which is hashed to determine the module name.
200             key += time.time(),
201 
202         module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
203         module_path = os.path.join(lib_dir, module_name + self.so_ext)
204 
205         have_module = os.path.isfile(module_path)
206         need_cythonize = not have_module
207 
208         if args.annotate:
209             html_file = os.path.join(lib_dir, module_name + '.html')
210             if not os.path.isfile(html_file):
211                 need_cythonize = True
212 
213         if need_cythonize:
214             c_include_dirs = args.include
215             if 'numpy' in code:
216                 import numpy
217                 c_include_dirs.append(numpy.get_include())
218             pyx_file = os.path.join(lib_dir, module_name + '.pyx')
219             pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())
220             with io.open(pyx_file, 'w', encoding='utf-8') as f:
221                 f.write(code)
222             extension = Extension(
223                 name = module_name,
224                 sources = [pyx_file],
225                 include_dirs = c_include_dirs,
226                 library_dirs = args.library_dirs,
227                 extra_compile_args = args.compile_args,
228                 extra_link_args = args.link_args,
229                 libraries = args.lib,
230                 language = 'c++' if args.cplus else 'c',
231             )
232             build_extension = self._get_build_extension()
233             try:
234                 opts = dict(
235                     quiet=quiet,
236                     annotate = args.annotate,
237                     force = True,
238                     )
239                 build_extension.extensions = cythonize([extension], **opts)
240             except CompileError:
241                 return
242 
243         if not have_module:
244             build_extension.build_temp = os.path.dirname(pyx_file)
245             build_extension.build_lib  = lib_dir
246             build_extension.run()
247             self._code_cache[key] = module_name
248 
249         module = imp.load_dynamic(module_name, module_path)
250         self._import_all(module)
251 
252         if args.annotate:
253             try:
254                 with io.open(html_file, encoding='utf-8') as f:
255                     annotated_html = f.read()
256             except IOError as e:
257                 # File could not be opened. Most likely the user has a version
258                 # of Cython before 0.15.1 (when `cythonize` learned the
259                 # `force` keyword argument) and has already compiled this
260                 # exact source without annotation.
261                 print('Cython completed successfully but the annotated '
262                       'source could not be read.', file=sys.stderr)
263                 print(e, file=sys.stderr)
264             else:
265                 return display.HTML(self.clean_annotated_html(annotated_html))
266 
267     @property
268     def so_ext(self):
269         """The extension suffix for compiled modules."""
270         try:
271             return self._so_ext
272         except AttributeError:
273             self._so_ext = self._get_build_extension().get_ext_filename('')
274             return self._so_ext
275 
276     def _get_build_extension(self):
277         dist = Distribution()
278         config_files = dist.find_config_files()
279         try:
280             config_files.remove('setup.cfg')
281         except ValueError:
282             pass
283         dist.parse_config_files(config_files)
284         build_extension = build_ext(dist)
285         build_extension.finalize_options()
286         return build_extension
287 
288     @staticmethod
289     def clean_annotated_html(html):
290         """Clean up the annotated HTML source.
291 
292         Strips the link to the generated C or C++ file, which we do not
293         present to the user.
294         """
295         r = re.compile('<p>Raw output: <a href="(.*)">(.*)</a>')
296         html = '\n'.join(l for l in html.splitlines() if not r.match(l))
297         return html
298 
299 __doc__ = __doc__.format(
300                 CYTHON_DOC = ' '*8 + CythonMagics.cython.__doc__,
301                 CYTHON_INLINE_DOC = ' '*8 + CythonMagics.cython_inline.__doc__,
302                 CYTHON_PYXIMPORT_DOC = ' '*8 + CythonMagics.cython_pyximport.__doc__,
303 )
304 
305 def load_ipython_extension(ip):
306     """Load the extension in IPython."""
307     ip.register_magics(CythonMagics)
308
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/IPython/extensions/cythonmagic.py b/IPython/extensions/cythonmagic.py
--- a/IPython/extensions/cythonmagic.py
+++ b/IPython/extensions/cythonmagic.py
@@ -41,6 +41,11 @@
 import sys
 import time
 
+try:
+    reload
+except NameError:   # Python 3
+    from imp import reload
+
 try:
     import hashlib
 except ImportError:

{"golden_diff": "diff --git a/IPython/extensions/cythonmagic.py b/IPython/extensions/cythonmagic.py\n--- a/IPython/extensions/cythonmagic.py\n+++ b/IPython/extensions/cythonmagic.py\n@@ -41,6 +41,11 @@\n import sys\n import time\n \n+try:\n+    reload\n+except NameError:   # Python 3\n+    from imp import reload\n+\n try:\n     import hashlib\n except ImportError:\n", "issue": "cython_pyximport reload broken in python3\npython3.3 notebook, tested in 0.13.1 but the code looks the same in HEAD:\n\n%%cython_pyximport foo\ndef f(x):\n    return 4.0*x\n\nexecute twice and you get \n\n```\n/usr/lib/python3/dist-packages/IPython/extensions/cythonmagic.py in cython_pyximport(self, line, cell)\n     99         if module_name in self._reloads:\n    100             module = self._reloads[module_name]\n--> 101             reload(module)\n    102         else:\n    103             __import__(module_name)\n\nNameError: global name 'reload' is not defined\n```\n\nimp.reload should be used here\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n=====================\nCython related magics\n=====================\n\nUsage\n=====\n\n``%%cython``\n\n{CYTHON_DOC}\n\n``%%cython_inline``\n\n{CYTHON_INLINE_DOC}\n\n``%%cython_pyximport``\n\n{CYTHON_PYXIMPORT_DOC}\n\nAuthor:\n* Brian Granger\n\nParts of this code were taken from Cython.inline.\n\"\"\"\n#-----------------------------------------------------------------------------\n# Copyright (C) 2010-2011, IPython Development Team.\n#\n# Distributed under the terms of the Modified BSD License.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#-----------------------------------------------------------------------------\n\nfrom __future__ import print_function\n\nimport imp\nimport io\nimport os\nimport re\nimport sys\nimport time\n\ntry:\n    import hashlib\nexcept ImportError:\n    import md5 as hashlib\n\nfrom distutils.core import Distribution, Extension\nfrom distutils.command.build_ext import build_ext\n\nfrom IPython.core import display\nfrom IPython.core import magic_arguments\nfrom IPython.core.magic import Magics, magics_class, cell_magic\nfrom IPython.testing.skipdoctest import skip_doctest\nfrom IPython.utils import py3compat\n\nimport Cython\nfrom Cython.Compiler.Errors import CompileError\nfrom Cython.Build.Dependencies import cythonize\n\n\n@magics_class\nclass CythonMagics(Magics):\n\n    def __init__(self, shell):\n        super(CythonMagics,self).__init__(shell)\n        self._reloads = {}\n        self._code_cache = {}\n\n    def _import_all(self, module):\n        for k,v in module.__dict__.items():\n            if not k.startswith('__'):\n                self.shell.push({k:v})\n\n    @cell_magic\n    def cython_inline(self, line, cell):\n        \"\"\"Compile and run a Cython code cell using Cython.inline.\n\n        This magic simply passes the body of the cell to Cython.inline\n        and returns the result. If the variables `a` and `b` are defined\n        in the user's namespace, here is a simple example that returns\n        their sum::\n\n            %%cython_inline\n            return a+b\n\n        For most purposes, we recommend the usage of the `%%cython` magic.\n        \"\"\"\n        locs = self.shell.user_global_ns\n        globs = self.shell.user_ns\n        return Cython.inline(cell, locals=locs, globals=globs)\n\n    @cell_magic\n    def cython_pyximport(self, line, cell):\n        \"\"\"Compile and import a Cython code cell using pyximport.\n\n        The contents of the cell are written to a `.pyx` file in the current\n        working directory, which is then imported using `pyximport`. This\n        magic requires a module name to be passed::\n\n            %%cython_pyximport modulename\n            def f(x):\n                return 2.0*x\n\n        The compiled module is then imported and all of its symbols are\n        injected into the user's namespace. For most purposes, we recommend\n        the usage of the `%%cython` magic.\n        \"\"\"\n        module_name = line.strip()\n        if not module_name:\n            raise ValueError('module name must be given')\n        fname = module_name + '.pyx'\n        with io.open(fname, 'w', encoding='utf-8') as f:\n            f.write(cell)\n        if 'pyximport' not in sys.modules:\n            import pyximport\n            pyximport.install(reload_support=True)\n        if module_name in self._reloads:\n            module = self._reloads[module_name]\n            reload(module)\n        else:\n            __import__(module_name)\n            module = sys.modules[module_name]\n            self._reloads[module_name] = module\n        self._import_all(module)\n\n    @magic_arguments.magic_arguments()\n    @magic_arguments.argument(\n        '-c', '--compile-args', action='append', default=[],\n        help=\"Extra flags to pass to compiler via the `extra_compile_args` \"\n             \"Extension flag (can be specified  multiple times).\"\n    )\n    @magic_arguments.argument(\n        '--link-args', action='append', default=[],\n        help=\"Extra flags to pass to linker via the `extra_link_args` \"\n             \"Extension flag (can be specified  multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-l', '--lib', action='append', default=[],\n        help=\"Add a library to link the extension against (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-L', dest='library_dirs', metavar='dir', action='append', default=[],\n        help=\"Add a path to the list of libary directories (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-I', '--include', action='append', default=[],\n        help=\"Add a path to the list of include directories (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-+', '--cplus', action='store_true', default=False,\n        help=\"Output a C++ rather than C file.\"\n    )\n    @magic_arguments.argument(\n        '-f', '--force', action='store_true', default=False,\n        help=\"Force the compilation of a new module, even if the source has been \"\n             \"previously compiled.\"\n    )\n    @magic_arguments.argument(\n        '-a', '--annotate', action='store_true', default=False,\n        help=\"Produce a colorized HTML version of the source.\"\n    )\n    @cell_magic\n    def cython(self, line, cell):\n        \"\"\"Compile and import everything from a Cython code cell.\n\n        The contents of the cell are written to a `.pyx` file in the\n        directory `IPYTHONDIR/cython` using a filename with the hash of the\n        code. This file is then cythonized and compiled. The resulting module\n        is imported and all of its symbols are injected into the user's\n        namespace. The usage is similar to that of `%%cython_pyximport` but\n        you don't have to pass a module name::\n\n            %%cython\n            def f(x):\n                return 2.0*x\n\n        To compile OpenMP codes, pass the required  `--compile-args`\n        and `--link-args`.  For example with gcc::\n\n            %%cython --compile-args=-fopenmp --link-args=-fopenmp\n            ...\n        \"\"\"\n        args = magic_arguments.parse_argstring(self.cython, line)\n        code = cell if cell.endswith('\\n') else cell+'\\n'\n        lib_dir = os.path.join(self.shell.ipython_dir, 'cython')\n        quiet = True\n        key = code, sys.version_info, sys.executable, Cython.__version__\n\n        if not os.path.exists(lib_dir):\n            os.makedirs(lib_dir)\n\n        if args.force:\n            # Force a new module name by adding the current time to the\n            # key which is hashed to determine the module name.\n            key += time.time(),\n\n        module_name = \"_cython_magic_\" + hashlib.md5(str(key).encode('utf-8')).hexdigest()\n        module_path = os.path.join(lib_dir, module_name + self.so_ext)\n\n        have_module = os.path.isfile(module_path)\n        need_cythonize = not have_module\n\n        if args.annotate:\n            html_file = os.path.join(lib_dir, module_name + '.html')\n            if not os.path.isfile(html_file):\n                need_cythonize = True\n\n        if need_cythonize:\n            c_include_dirs = args.include\n            if 'numpy' in code:\n                import numpy\n                c_include_dirs.append(numpy.get_include())\n            pyx_file = os.path.join(lib_dir, module_name + '.pyx')\n            pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())\n            with io.open(pyx_file, 'w', encoding='utf-8') as f:\n                f.write(code)\n            extension = Extension(\n                name = module_name,\n                sources = [pyx_file],\n                include_dirs = c_include_dirs,\n                library_dirs = args.library_dirs,\n                extra_compile_args = args.compile_args,\n                extra_link_args = args.link_args,\n                libraries = args.lib,\n                language = 'c++' if args.cplus else 'c',\n            )\n            build_extension = self._get_build_extension()\n            try:\n                opts = dict(\n                    quiet=quiet,\n                    annotate = args.annotate,\n                    force = True,\n                    )\n                build_extension.extensions = cythonize([extension], **opts)\n            except CompileError:\n                return\n\n        if not have_module:\n            build_extension.build_temp = os.path.dirname(pyx_file)\n            build_extension.build_lib  = lib_dir\n            build_extension.run()\n            self._code_cache[key] = module_name\n\n        module = imp.load_dynamic(module_name, module_path)\n        self._import_all(module)\n\n        if args.annotate:\n            try:\n                with io.open(html_file, encoding='utf-8') as f:\n                    annotated_html = f.read()\n            except IOError as e:\n                # File could not be opened. Most likely the user has a version\n                # of Cython before 0.15.1 (when `cythonize` learned the\n                # `force` keyword argument) and has already compiled this\n                # exact source without annotation.\n                print('Cython completed successfully but the annotated '\n                      'source could not be read.', file=sys.stderr)\n                print(e, file=sys.stderr)\n            else:\n                return display.HTML(self.clean_annotated_html(annotated_html))\n\n    @property\n    def so_ext(self):\n        \"\"\"The extension suffix for compiled modules.\"\"\"\n        try:\n            return self._so_ext\n        except AttributeError:\n            self._so_ext = self._get_build_extension().get_ext_filename('')\n            return self._so_ext\n\n    def _get_build_extension(self):\n        dist = Distribution()\n        config_files = dist.find_config_files()\n        try:\n            config_files.remove('setup.cfg')\n        except ValueError:\n            pass\n        dist.parse_config_files(config_files)\n        build_extension = build_ext(dist)\n        build_extension.finalize_options()\n        return build_extension\n\n    @staticmethod\n    def clean_annotated_html(html):\n        \"\"\"Clean up the annotated HTML source.\n\n        Strips the link to the generated C or C++ file, which we do not\n        present to the user.\n        \"\"\"\n        r = re.compile('<p>Raw output: <a href=\"(.*)\">(.*)</a>')\n        html = '\\n'.join(l for l in html.splitlines() if not r.match(l))\n        return html\n\n__doc__ = __doc__.format(\n                CYTHON_DOC = ' '*8 + CythonMagics.cython.__doc__,\n                CYTHON_INLINE_DOC = ' '*8 + CythonMagics.cython_inline.__doc__,\n                CYTHON_PYXIMPORT_DOC = ' '*8 + CythonMagics.cython_pyximport.__doc__,\n)\n\ndef load_ipython_extension(ip):\n    \"\"\"Load the extension in IPython.\"\"\"\n    ip.register_magics(CythonMagics)\n", "path": "IPython/extensions/cythonmagic.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n=====================\nCython related magics\n=====================\n\nUsage\n=====\n\n``%%cython``\n\n{CYTHON_DOC}\n\n``%%cython_inline``\n\n{CYTHON_INLINE_DOC}\n\n``%%cython_pyximport``\n\n{CYTHON_PYXIMPORT_DOC}\n\nAuthor:\n* Brian Granger\n\nParts of this code were taken from Cython.inline.\n\"\"\"\n#-----------------------------------------------------------------------------\n# Copyright (C) 2010-2011, IPython Development Team.\n#\n# Distributed under the terms of the Modified BSD License.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#-----------------------------------------------------------------------------\n\nfrom __future__ import print_function\n\nimport imp\nimport io\nimport os\nimport re\nimport sys\nimport time\n\ntry:\n    reload\nexcept NameError:   # Python 3\n    from imp import reload\n\ntry:\n    import hashlib\nexcept ImportError:\n    import md5 as hashlib\n\nfrom distutils.core import Distribution, Extension\nfrom distutils.command.build_ext import build_ext\n\nfrom IPython.core import display\nfrom IPython.core import magic_arguments\nfrom IPython.core.magic import Magics, magics_class, cell_magic\nfrom IPython.testing.skipdoctest import skip_doctest\nfrom IPython.utils import py3compat\n\nimport Cython\nfrom Cython.Compiler.Errors import CompileError\nfrom Cython.Build.Dependencies import cythonize\n\n\n@magics_class\nclass CythonMagics(Magics):\n\n    def __init__(self, shell):\n        super(CythonMagics,self).__init__(shell)\n        self._reloads = {}\n        self._code_cache = {}\n\n    def _import_all(self, module):\n        for k,v in module.__dict__.items():\n            if not k.startswith('__'):\n                self.shell.push({k:v})\n\n    @cell_magic\n    def cython_inline(self, line, cell):\n        \"\"\"Compile and run a Cython code cell using Cython.inline.\n\n        This magic simply passes the body of the cell to Cython.inline\n        and returns the result. If the variables `a` and `b` are defined\n        in the user's namespace, here is a simple example that returns\n        their sum::\n\n            %%cython_inline\n            return a+b\n\n        For most purposes, we recommend the usage of the `%%cython` magic.\n        \"\"\"\n        locs = self.shell.user_global_ns\n        globs = self.shell.user_ns\n        return Cython.inline(cell, locals=locs, globals=globs)\n\n    @cell_magic\n    def cython_pyximport(self, line, cell):\n        \"\"\"Compile and import a Cython code cell using pyximport.\n\n        The contents of the cell are written to a `.pyx` file in the current\n        working directory, which is then imported using `pyximport`. This\n        magic requires a module name to be passed::\n\n            %%cython_pyximport modulename\n            def f(x):\n                return 2.0*x\n\n        The compiled module is then imported and all of its symbols are\n        injected into the user's namespace. For most purposes, we recommend\n        the usage of the `%%cython` magic.\n        \"\"\"\n        module_name = line.strip()\n        if not module_name:\n            raise ValueError('module name must be given')\n        fname = module_name + '.pyx'\n        with io.open(fname, 'w', encoding='utf-8') as f:\n            f.write(cell)\n        if 'pyximport' not in sys.modules:\n            import pyximport\n            pyximport.install(reload_support=True)\n        if module_name in self._reloads:\n            module = self._reloads[module_name]\n            reload(module)\n        else:\n            __import__(module_name)\n            module = sys.modules[module_name]\n            self._reloads[module_name] = module\n        self._import_all(module)\n\n    @magic_arguments.magic_arguments()\n    @magic_arguments.argument(\n        '-c', '--compile-args', action='append', default=[],\n        help=\"Extra flags to pass to compiler via the `extra_compile_args` \"\n             \"Extension flag (can be specified  multiple times).\"\n    )\n    @magic_arguments.argument(\n        '--link-args', action='append', default=[],\n        help=\"Extra flags to pass to linker via the `extra_link_args` \"\n             \"Extension flag (can be specified  multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-l', '--lib', action='append', default=[],\n        help=\"Add a library to link the extension against (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-L', dest='library_dirs', metavar='dir', action='append', default=[],\n        help=\"Add a path to the list of libary directories (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-I', '--include', action='append', default=[],\n        help=\"Add a path to the list of include directories (can be specified \"\n             \"multiple times).\"\n    )\n    @magic_arguments.argument(\n        '-+', '--cplus', action='store_true', default=False,\n        help=\"Output a C++ rather than C file.\"\n    )\n    @magic_arguments.argument(\n        '-f', '--force', action='store_true', default=False,\n        help=\"Force the compilation of a new module, even if the source has been \"\n             \"previously compiled.\"\n    )\n    @magic_arguments.argument(\n        '-a', '--annotate', action='store_true', default=False,\n        help=\"Produce a colorized HTML version of the source.\"\n    )\n    @cell_magic\n    def cython(self, line, cell):\n        \"\"\"Compile and import everything from a Cython code cell.\n\n        The contents of the cell are written to a `.pyx` file in the\n        directory `IPYTHONDIR/cython` using a filename with the hash of the\n        code. This file is then cythonized and compiled. The resulting module\n        is imported and all of its symbols are injected into the user's\n        namespace. The usage is similar to that of `%%cython_pyximport` but\n        you don't have to pass a module name::\n\n            %%cython\n            def f(x):\n                return 2.0*x\n\n        To compile OpenMP codes, pass the required  `--compile-args`\n        and `--link-args`.  For example with gcc::\n\n            %%cython --compile-args=-fopenmp --link-args=-fopenmp\n            ...\n        \"\"\"\n        args = magic_arguments.parse_argstring(self.cython, line)\n        code = cell if cell.endswith('\\n') else cell+'\\n'\n        lib_dir = os.path.join(self.shell.ipython_dir, 'cython')\n        quiet = True\n        key = code, sys.version_info, sys.executable, Cython.__version__\n\n        if not os.path.exists(lib_dir):\n            os.makedirs(lib_dir)\n\n        if args.force:\n            # Force a new module name by adding the current time to the\n            # key which is hashed to determine the module name.\n            key += time.time(),\n\n        module_name = \"_cython_magic_\" + hashlib.md5(str(key).encode('utf-8')).hexdigest()\n        module_path = os.path.join(lib_dir, module_name + self.so_ext)\n\n        have_module = os.path.isfile(module_path)\n        need_cythonize = not have_module\n\n        if args.annotate:\n            html_file = os.path.join(lib_dir, module_name + '.html')\n            if not os.path.isfile(html_file):\n                need_cythonize = True\n\n        if need_cythonize:\n            c_include_dirs = args.include\n            if 'numpy' in code:\n                import numpy\n                c_include_dirs.append(numpy.get_include())\n            pyx_file = os.path.join(lib_dir, module_name + '.pyx')\n            pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())\n            with io.open(pyx_file, 'w', encoding='utf-8') as f:\n                f.write(code)\n            extension = Extension(\n                name = module_name,\n                sources = [pyx_file],\n                include_dirs = c_include_dirs,\n                library_dirs = args.library_dirs,\n                extra_compile_args = args.compile_args,\n                extra_link_args = args.link_args,\n                libraries = args.lib,\n                language = 'c++' if args.cplus else 'c',\n            )\n            build_extension = self._get_build_extension()\n            try:\n                opts = dict(\n                    quiet=quiet,\n                    annotate = args.annotate,\n                    force = True,\n                    )\n                build_extension.extensions = cythonize([extension], **opts)\n            except CompileError:\n                return\n\n        if not have_module:\n            build_extension.build_temp = os.path.dirname(pyx_file)\n            build_extension.build_lib  = lib_dir\n            build_extension.run()\n            self._code_cache[key] = module_name\n\n        module = imp.load_dynamic(module_name, module_path)\n        self._import_all(module)\n\n        if args.annotate:\n            try:\n                with io.open(html_file, encoding='utf-8') as f:\n                    annotated_html = f.read()\n            except IOError as e:\n                # File could not be opened. Most likely the user has a version\n                # of Cython before 0.15.1 (when `cythonize` learned the\n                # `force` keyword argument) and has already compiled this\n                # exact source without annotation.\n                print('Cython completed successfully but the annotated '\n                      'source could not be read.', file=sys.stderr)\n                print(e, file=sys.stderr)\n            else:\n                return display.HTML(self.clean_annotated_html(annotated_html))\n\n    @property\n    def so_ext(self):\n        \"\"\"The extension suffix for compiled modules.\"\"\"\n        try:\n            return self._so_ext\n        except AttributeError:\n            self._so_ext = self._get_build_extension().get_ext_filename('')\n            return self._so_ext\n\n    def _get_build_extension(self):\n        dist = Distribution()\n        config_files = dist.find_config_files()\n        try:\n            config_files.remove('setup.cfg')\n        except ValueError:\n            pass\n        dist.parse_config_files(config_files)\n        build_extension = build_ext(dist)\n        build_extension.finalize_options()\n        return build_extension\n\n    @staticmethod\n    def clean_annotated_html(html):\n        \"\"\"Clean up the annotated HTML source.\n\n        Strips the link to the generated C or C++ file, which we do not\n        present to the user.\n        \"\"\"\n        r = re.compile('<p>Raw output: <a href=\"(.*)\">(.*)</a>')\n        html = '\\n'.join(l for l in html.splitlines() if not r.match(l))\n        return html\n\n__doc__ = __doc__.format(\n                CYTHON_DOC = ' '*8 + CythonMagics.cython.__doc__,\n                CYTHON_INLINE_DOC = ' '*8 + CythonMagics.cython_inline.__doc__,\n                CYTHON_PYXIMPORT_DOC = ' '*8 + CythonMagics.cython_pyximport.__doc__,\n)\n\ndef load_ipython_extension(ip):\n    \"\"\"Load the extension in IPython.\"\"\"\n    ip.register_magics(CythonMagics)\n", "path": "IPython/extensions/cythonmagic.py"}]}