Skip to content

Commit

Permalink
Merge pull request ipython#4870 from y-p/PR_ipython_directive
Browse files Browse the repository at this point in the history
ipython_directive, report except/warn in block and add :okexcept: :okwarning: options to suppress
  • Loading branch information
takluyver committed Jan 30, 2014
2 parents ba0e009 + 7be28e5 commit 120950a
Showing 1 changed file with 87 additions and 19 deletions.
106 changes: 87 additions & 19 deletions IPython/sphinxext/ipython_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@
See http://matplotlib.org/sampledoc/ipython_directive.html for additional
documentation.
Pseudo-Decorators
=================
In addition to the Pseudo-Decorators/options described at the above link,
several enhancements have been made.
The directive will emit a message to the console at build-time if
code-execution resulted in an exception or warning. You can suppress these on
a per-block basis by specifying the :okexcept: or :okwarning: options:
.. code-block:: rst
.. ipython::
:okexcept:
:okwarning:
In [1]: 1/0
In [2]: # raise warning.
ToDo
----
Expand Down Expand Up @@ -110,6 +128,7 @@
import sys
import tempfile
import ast
import warnings

# To keep compatibility with various python versions
try:
Expand Down Expand Up @@ -216,6 +235,12 @@ def block_parser(part, rgxin, rgxout, fmtin, fmtout):
if matchout or nextline.startswith('#'):
break
elif nextline.startswith(continuation):
# The default ipython_rgx* treat the space following the colon as optional.
# However, If the space is there we must consume it or code
# employing the cython_magic extension will fail to execute.
#
# This works with the default ipython_rgx* patterns,
# If you modify them, YMMV.
nextline = nextline[Nc:]
if nextline and nextline[0] == ' ':
nextline = nextline[1:]
Expand Down Expand Up @@ -290,6 +315,10 @@ def __init__(self, exec_lines=None):
self.is_suppress = False

# Optionally, provide more detailed information to shell.
# this is assigned by the SetUp method of IPythonDirective
# to point at itself.
#
# So, you can access handy things at self.directive.state
self.directive = None

# on the first call to the savefig decorator, we'll import
Expand Down Expand Up @@ -362,6 +391,8 @@ def process_input(self, data, input_prompt, lineno):
is_doctest = (decorator is not None and \
decorator.startswith('@doctest')) or self.is_doctest
is_suppress = decorator=='@suppress' or self.is_suppress
is_okexcept = decorator=='@okexcept' or self.is_okexcept
is_okwarning = decorator=='@okwarning' or self.is_okwarning
is_savefig = decorator is not None and \
decorator.startswith('@savefig')

Expand All @@ -385,28 +416,30 @@ def process_input(self, data, input_prompt, lineno):
else:
store_history = True

for i, line in enumerate(input_lines):
if line.endswith(';'):
is_semicolon = True

if i == 0:
# process the first input line
if is_verbatim:
self.process_input_line('')
self.IP.execution_count += 1 # increment it anyway
# Note: catch_warnings is not thread safe
with warnings.catch_warnings(record=True) as ws:
for i, line in enumerate(input_lines):
if line.endswith(';'):
is_semicolon = True

if i == 0:
# process the first input line
if is_verbatim:
self.process_input_line('')
self.IP.execution_count += 1 # increment it anyway
else:
# only submit the line in non-verbatim mode
self.process_input_line(line, store_history=store_history)
formatted_line = '%s %s'%(input_prompt, line)
else:
# only submit the line in non-verbatim mode
self.process_input_line(line, store_history=store_history)
formatted_line = '%s %s'%(input_prompt, line)
else:
# process a continuation line
if not is_verbatim:
self.process_input_line(line, store_history=store_history)
# process a continuation line
if not is_verbatim:
self.process_input_line(line, store_history=store_history)

formatted_line = '%s %s'%(continuation, line)
formatted_line = '%s %s'%(continuation, line)

if not is_suppress:
ret.append(formatted_line)
if not is_suppress:
ret.append(formatted_line)

if not is_suppress and len(rest.strip()) and is_verbatim:
# the "rest" is the standard output of the
Expand All @@ -421,6 +454,37 @@ def process_input(self, data, input_prompt, lineno):
elif is_semicolon: # get spacing right
ret.append('')

# context information
filename = "Unknown"
lineno = 0
if self.directive.state:
filename = self.directive.state.document.current_source
lineno = self.directive.state.document.current_line

# output any exceptions raised during execution to stdout
# unless :okexcept: has been specified.
if not is_okexcept and "Traceback" in output:
s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
sys.stdout.write('\n\n>>>' + ('-' * 73))
sys.stdout.write(s)
sys.stdout.write(output)
sys.stdout.write('<<<' + ('-' * 73) + '\n\n')

# output any warning raised during execution to stdout
# unless :okwarning: has been specified.
if not is_okwarning:
for w in ws:
s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
sys.stdout.write('\n\n>>>' + ('-' * 73))
sys.stdout.write(s)
sys.stdout.write(('-' * 76) + '\n')
s=warnings.formatwarning(w.message, w.category,
w.filename, w.lineno, w.line)
sys.stdout.write(s)
sys.stdout.write('<<<' + ('-' * 73) + '\n')

self.cout.truncate(0)
return (ret, input_lines, output, is_doctest, decorator, image_file,
image_directive)
Expand Down Expand Up @@ -662,6 +726,8 @@ class IPythonDirective(Directive):
'suppress' : directives.flag,
'verbatim' : directives.flag,
'doctest' : directives.flag,
'okexcept': directives.flag,
'okwarning': directives.flag
}

shell = None
Expand Down Expand Up @@ -759,6 +825,8 @@ def run(self):
self.shell.is_suppress = 'suppress' in options
self.shell.is_doctest = 'doctest' in options
self.shell.is_verbatim = 'verbatim' in options
self.shell.is_okexcept = 'okexcept' in options
self.shell.is_okwarning = 'okwarning' in options

# handle pure python code
if 'python' in self.arguments:
Expand Down

0 comments on commit 120950a

Please sign in to comment.