From ce22f49932fd4f071804e59f3c9d3f7042b917dd 2018-09-14 13:06:28 From: Matthias Bussonnier Date: 2018-09-14 13:06:28 Subject: [PATCH] Fix magic directive and role. We were directly modifying state instead of using blessed API (also some api will change so be future proof with sphinx master). This should restore some ability of the :magic: and :cellmagic: directive to both support link to magics name when the text in the directive contains (or not) leading % and %%, it will also automatically prepend the right number of % for magics and cell magics. A couple of other related fixes. --- diff --git a/docs/source/config/extensions/autoreload.rst b/docs/source/config/extensions/autoreload.rst index 619605e..3b35489 100644 --- a/docs/source/config/extensions/autoreload.rst +++ b/docs/source/config/extensions/autoreload.rst @@ -4,4 +4,6 @@ autoreload ========== +.. magic:: autoreload + .. automodule:: IPython.extensions.autoreload diff --git a/docs/source/interactive/autoawait.rst b/docs/source/interactive/autoawait.rst index cb1d4f9..f52aae5 100644 --- a/docs/source/interactive/autoawait.rst +++ b/docs/source/interactive/autoawait.rst @@ -58,7 +58,7 @@ Should behave as expected in the IPython REPL:: You can use the ``c.InteractiveShell.autoawait`` configuration option and set it to :any:`False` to deactivate automatic wrapping of asynchronous code. You can -also use the :magic:`%autoawait` magic to toggle the behavior at runtime:: +also use the :magic:`autoawait` magic to toggle the behavior at runtime:: In [1]: %autoawait False @@ -127,7 +127,7 @@ Effects on IPython.embed() IPython core being asynchronous, the use of ``IPython.embed()`` will now require a loop to run. By default IPython will use a fake coroutine runner which should allow ``IPython.embed()`` to be nested. Though this will prevent usage of the -``autoawait`` feature when using IPython embed. +:magic:`autoawait` feature when using IPython embed. You can set explicitly a coroutine runner for ``embed()`` if you desire to run asynchronous code, the exact behavior is though undefined. @@ -230,11 +230,12 @@ Update ipykernel to version 5.0 or greater:: # or conda install ipykernel ipython --upgrade -This should automatically enable ``autoawait`` integration. Unlike terminal -IPython, all code runs on ``asyncio`` eventloop, so creating a loop by hand will -not work, including with magics like ``%run`` or other frameworks that create -the eventloop themselves. In cases like these you can try to use projects like -`nest_asyncio `_ and follow `this discussion +This should automatically enable :magic:`autoawait` integration. Unlike +terminal IPython, all code runs on ``asyncio`` eventloop, so creating a loop by +hand will not work, including with magics like :magic:`%run` or other +frameworks that create the eventloop themselves. In cases like these you can +try to use projects like `nest_asyncio +`_ and follow `this discussion `_ Difference between terminal IPython and IPykernel @@ -242,7 +243,7 @@ Difference between terminal IPython and IPykernel The exact asynchronous code running behavior varies between Terminal IPython and IPykernel. The root cause of this behavior is due to IPykernel having a -*persistent* ``asyncio`` loop running, while Terminal IPython starts and stops a +*persistent* `asyncio` loop running, while Terminal IPython starts and stops a loop for each code block. This can lead to surprising behavior in some case if you are used to manipulate asyncio loop yourself, see for example :ghissue:`11303` for a longer discussion but here are some of the astonishing diff --git a/docs/source/whatsnew/version7.rst b/docs/source/whatsnew/version7.rst index 286c605..f5a32cd 100644 --- a/docs/source/whatsnew/version7.rst +++ b/docs/source/whatsnew/version7.rst @@ -114,10 +114,10 @@ Non-Asynchronous code ~~~~~~~~~~~~~~~~~~~~~ As the internal API of IPython are now asynchronous, IPython need to run under -an even loop. In order to allow many workflow, (like using the ``%run`` magic, -or copy_pasting code that explicitly starts/stop event loop), when top-level code -is detected as not being asynchronous, IPython code is advanced via a -pseudo-synchronous runner, and will not may not advance pending tasks. +an even loop. In order to allow many workflow, (like using the :magic:`%run` +magic, or copy_pasting code that explicitly starts/stop event loop), when +top-level code is detected as not being asynchronous, IPython code is advanced +via a pseudo-synchronous runner, and will not may not advance pending tasks. Change to Nested Embed ~~~~~~~~~~~~~~~~~~~~~~ @@ -151,11 +151,17 @@ minrk, njsmith, pganssle, tacaswell, takluyver , vidartf ... And many others. Autoreload Improvement ---------------------- -The magic ``%autoreload 2`` now captures new methods added to classes. Earlier, only methods existing as of the initial import were being tracked and updated. +The magic :magic:`%autoreload 2 ` now captures new methods added to +classes. Earlier, only methods existing as of the initial import were being +tracked and updated. -This new feature helps dual environment development - Jupyter+IDE - where the code gradually moves from notebook cells to package files, as it gets structured. +This new feature helps dual environment development - Jupyter+IDE - where the +code gradually moves from notebook cells to package files, as it gets +structured. -**Example**: An instance of the class `MyClass` will be able to access the method `cube()` after it is uncommented and the file `file1.py` saved on disk. +**Example**: An instance of the class ``MyClass`` will be able to access the +method ``cube()`` after it is uncommented and the file ``file1.py`` saved on +disk. ..code:: @@ -191,13 +197,14 @@ Misc The autoindent feature that was deprecated in 5.x was re-enabled and un-deprecated in :ghpull:`11257` -Make ``%run -n -i ...`` work correctly. Earlier, if ``%run`` was passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308` +Make :magic:`%run -n -i ... ` work correctly. Earlier, if :magic:`%run` was +passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308` -The ``%%script`` (as well as ``%%bash``, ``ruby``... ) cell magics now raise -by default if the return code of the given code is non-zero (thus halting -execution of further cells in a notebook). The behavior can be disable by -passing the ``--no-raise-error`` flag. +The :cellmagic:`%%script`` (as well as :cellmagic:`%%bash``, +:cellmagic:`%%ruby``... ) cell magics now raise by default if the return code of +the given code is non-zero (thus halting execution of further cells in a +notebook). The behavior can be disable by passing the ``--no-raise-error`` flag. Deprecations diff --git a/docs/sphinxext/github.py b/docs/sphinxext/github.py index 8f0ffc0..dcc0250 100644 --- a/docs/sphinxext/github.py +++ b/docs/sphinxext/github.py @@ -19,6 +19,9 @@ Authors from docutils import nodes, utils from docutils.parsers.rst.roles import set_classes +from sphinx.util.logging import getLogger + +info = getLogger(__name__).info def make_link_node(rawtext, app, type, slug, options): """Create a link to a github resource. @@ -75,7 +78,7 @@ def ghissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app - #app.info('issue %r' % text) + #info('issue %r' % text) if 'pull' in name.lower(): category = 'pull' elif 'issue' in name.lower(): @@ -105,7 +108,7 @@ def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]): :param content: The directive content for customization. """ app = inliner.document.settings.env.app - #app.info('user link %r' % text) + #info('user link %r' % text) ref = 'https://www.github.com/' + text node = nodes.reference(rawtext, text, refuri=ref, **options) return [node], [] @@ -126,7 +129,7 @@ def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]): :param content: The directive content for customization. """ app = inliner.document.settings.env.app - #app.info('user link %r' % text) + #info('user link %r' % text) try: base = app.config.github_project_url if not base: @@ -146,7 +149,7 @@ def setup(app): :param app: Sphinx application context. """ - app.info('Initializing GitHub plugin') + info('Initializing GitHub plugin') app.add_role('ghissue', ghissue_role) app.add_role('ghpull', ghissue_role) app.add_role('ghuser', ghuser_role) diff --git a/docs/sphinxext/magics.py b/docs/sphinxext/magics.py index 913a0c5..d96b41c 100644 --- a/docs/sphinxext/magics.py +++ b/docs/sphinxext/magics.py @@ -37,9 +37,10 @@ class CellMagicRole(LineMagicRole): def setup(app): app.add_object_type('magic', 'magic', 'pair: %s; magic command', parse_magic) - StandardDomain.roles['magic'] = LineMagicRole() + app.add_role_to_domain('std', 'magic', LineMagicRole(), override=True) + app.add_object_type('cellmagic', 'cellmagic', 'pair: %s; cell magic', parse_cell_magic) - StandardDomain.roles['cellmagic'] = CellMagicRole() + app.add_role_to_domain('std', 'cellmagic', CellMagicRole(), override=True) metadata = {'parallel_read_safe': True, 'parallel_write_safe': True} return metadata