Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Cleanup console output during build #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions sphinx_gallery/docs_resolv.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import shelve
import sys

from sphinx.util.console import fuchsia

# Try Python 2 first, otherwise load from Python 3
try:
import cPickle as pickle
Expand All @@ -29,6 +27,11 @@

from io import StringIO

from . import sphinx_compatibility


logger = sphinx_compatibility.getLogger('sphinx-gallery')


def _get_data(url):
"""Helper function to get data over http or from a local file"""
Expand Down Expand Up @@ -348,15 +351,14 @@ def _embed_code_links(app, gallery_conf, gallery_dir):
src_gallery_dir)

except HTTPError as e:
print("The following HTTP Error has occurred:\n")
print(e.code)
logger.warning("The following HTTP Error has occurred: %d", e.code)
except URLError as e:
print("\n...\n"
"Warning: Embedding the documentation hyperlinks requires "
"Internet access.\nPlease check your network connection.\n"
"Unable to continue embedding `{0}` links due to a URL "
"Error:\n".format(this_module))
print(e.args)
logger.warning(
"Embedding the documentation hyperlinks requires Internet "
"access.\nPlease check your network connection.\nUnable to "
"continue embedding `%s` links due to a URL Error:\n%s",
this_module,
str(e.args))

html_gallery_dir = os.path.abspath(os.path.join(app.builder.outdir,
gallery_dir))
Expand All @@ -370,8 +372,8 @@ def _embed_code_links(app, gallery_conf, gallery_dir):
flat = [[dirpath, filename]
for dirpath, _, filenames in os.walk(html_gallery_dir)
for filename in filenames]
iterator = app.status_iterator(
flat, os.path.basename(html_gallery_dir), colorfunc=fuchsia,
iterator = sphinx_compatibility.status_iterator(
flat, gallery_dir, color='fuchsia',
length=len(flat), stringify_func=lambda x: os.path.basename(x[1]))
for dirpath, fname in iterator:
full_fname = os.path.join(html_gallery_dir, dirpath, fname)
Expand Down Expand Up @@ -400,8 +402,8 @@ def _embed_code_links(app, gallery_conf, gallery_dir):
extra = e.code
else:
extra = e.reason
print("\n\t\tError resolving %s.%s: %r (%s)"
% (cobj['module'], cobj['name'], e, extra))
logger.warning("Error resolving %s.%s: %r (%s)",
cobj['module'], cobj['name'], e, extra)
continue

if link is not None:
Expand Down Expand Up @@ -451,7 +453,8 @@ def embed_code_links(app, exception):
if app.builder.name not in ['html', 'readthedocs']:
return

print('Embedding documentation hyperlinks in examples..')
logger.info('Embedding documentation hyperlinks in examples ...',
color='white')

gallery_conf = app.config.sphinx_gallery_conf

Expand Down
43 changes: 25 additions & 18 deletions sphinx_gallery/gen_gallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import os

from . import glr_path_static
from . import sphinx_compatibility
from .gen_rst import generate_dir_rst, SPHX_GLR_SIG
from .docs_resolv import embed_code_links
from .downloads import generate_zipfiles
Expand All @@ -41,6 +42,8 @@
'expected_failing_examples': set(),
}

logger = sphinx_compatibility.getLogger('sphinx-gallery')


def clean_gallery_out(build_dir):
"""Deletes images under the sphx_glr namespace in the build directory"""
Expand Down Expand Up @@ -99,24 +102,28 @@ def parse_config(app):
https://sphinx-gallery.readthedocs.io/en/latest/advanced_configuration.html#references-to-examples"""

gallery_conf['backreferences_dir'] = gallery_conf['mod_example_dir']
app.warn("Old configuration for backreferences detected \n"
"using the configuration variable `mod_example_dir`\n"
+ backreferences_warning
+ update_msg, prefix="DeprecationWarning: ")
logger.warning(
"Old configuration for backreferences detected \n"
"using the configuration variable `mod_example_dir`\n"
"%s%s",
backreferences_warning,
update_msg,
type=DeprecationWarning)

elif gallery_conf['backreferences_dir'] is None:
no_care_msg = """
If you don't care about this features set in your conf.py
'backreferences_dir': False\n"""

app.warn(backreferences_warning + no_care_msg)
logger.warning(backreferences_warning + no_care_msg)

gallery_conf['backreferences_dir'] = os.path.join(
'modules', 'generated')
app.warn("using old default 'backreferences_dir':'{}'.\n"
" This will be disabled in future releases\n".format(
gallery_conf['backreferences_dir']),
prefix="DeprecationWarning: ")
logger.warning(
"Using old default 'backreferences_dir':'%s'.\n"
"This will be disabled in future releases\n",
gallery_conf['backreferences_dir'],
type=DeprecationWarning)

# this assures I can call the config in other places
app.config.sphinx_gallery_conf = gallery_conf
Expand Down Expand Up @@ -150,7 +157,7 @@ def generate_gallery_rst(app):
Start the sphinx-gallery configuration and recursively scan the examples
directories in order to populate the examples gallery
"""
print('Generating gallery')
logger.info('Generating gallery...', color='white')
gallery_conf = parse_config(app)

clean_gallery_out(app.builder.outdir)
Expand Down Expand Up @@ -201,12 +208,12 @@ def generate_gallery_rst(app):
fhindex.flush()

if gallery_conf['plot_gallery']:
print("Computation time summary:")
logger.info("Computation time summary:", color='white')
for time_elapsed, fname in sorted(computation_times)[::-1]:
if time_elapsed is not None:
print("\t- %s : %.2g sec" % (fname, time_elapsed))
logger.info("\t- %s : %.2g sec", fname, time_elapsed)
else:
print("\t- %s : not run" % fname)
logger.info("\t- %s : not run", fname)


def touch_empty_backreferences(app, what, name, obj, options, lines):
Expand Down Expand Up @@ -248,13 +255,11 @@ def sumarize_failing_examples(app, exception):

examples_expected_to_fail = failing_examples.intersection(
expected_failing_examples)
expected_fail_msg = []
if examples_expected_to_fail:
expected_fail_msg.append("\n\nExamples failing as expected:")
logger.info("Examples failing as expected:", color='brown')
for fail_example in examples_expected_to_fail:
expected_fail_msg.append(fail_example + ' failed leaving traceback:\n' +
gallery_conf['failing_examples'][fail_example] + '\n')
print("\n".join(expected_fail_msg))
logger.info('%s failed leaving traceback:', fail_example)
logger.info(gallery_conf['failing_examples'][fail_example])

examples_not_expected_to_fail = failing_examples.difference(
expected_failing_examples)
Expand Down Expand Up @@ -288,6 +293,8 @@ def default_getter(conf):

def setup(app):
"""Setup sphinx-gallery sphinx extension"""
sphinx_compatibility._app = app

app.add_config_value('sphinx_gallery_conf', DEFAULT_GALLERY_CONF, 'html')
for key in ['plot_gallery', 'abort_on_example_error']:
app.add_config_value(key, get_default_config_value(key), 'html')
Expand Down
71 changes: 24 additions & 47 deletions sphinx_gallery/gen_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import subprocess
import sys
import traceback
import warnings


# Try Python 2 first, otherwise load from Python 3
Expand Down Expand Up @@ -72,6 +71,7 @@ def prefixed_lines():
import matplotlib.pyplot as plt

from . import glr_path_static
from . import sphinx_compatibility
from .backreferences import write_backreferences, _thumbnail_div
from .downloads import CODE_DOWNLOAD
from .py_source_parser import (get_docstring_and_rest,
Expand All @@ -85,28 +85,10 @@ def prefixed_lines():
basestring = str
unicode = str

logger = sphinx_compatibility.getLogger('sphinx-gallery')

###############################################################################


class Tee(object):
"""A tee object to redirect streams to multiple outputs"""

def __init__(self, file1, file2):
self.file1 = file1
self.file2 = file2

def write(self, data):
self.file1.write(data)
self.file2.write(data)

def flush(self):
self.file1.flush()
self.file2.flush()

# When called from a local terminal seaborn needs it in Python3
def isatty(self):
self.file1.isatty()
###############################################################################


class MixedEncodingStringIO(StringIO):
Expand Down Expand Up @@ -355,8 +337,8 @@ def scale_image(in_fname, out_fname, max_width, max_height):
try:
subprocess.call(["optipng", "-quiet", "-o", "9", out_fname])
except Exception:
warnings.warn('Install optipng to reduce the size of the \
generated images')
logger.warning(
'Install optipng to reduce the size of the generated images')


def save_thumbnail(image_path_template, src_file, gallery_conf):
Expand Down Expand Up @@ -392,11 +374,8 @@ def save_thumbnail(image_path_template, src_file, gallery_conf):
def generate_dir_rst(src_dir, target_dir, gallery_conf, seen_backrefs):
"""Generate the gallery reStructuredText for an example directory"""
if not os.path.exists(os.path.join(src_dir, 'README.txt')):
print(80 * '_')
print('Example directory %s does not have a README.txt file' %
src_dir)
print('Skipping this directory')
print(80 * '_')
logger.warning('Skipping example directory without a README.txt file',
location=src_dir)
return "", [] # because string is an expected return type

with open(os.path.join(src_dir, 'README.txt')) as fid:
Expand All @@ -411,9 +390,13 @@ def generate_dir_rst(src_dir, target_dir, gallery_conf, seen_backrefs):
entries_text = []
computation_times = []
build_target_dir = os.path.relpath(target_dir, gallery_conf['src_dir'])
for fname in sorted_listdir:
amount_of_code, time_elapsed = \
generate_file_rst(fname, target_dir, src_dir, gallery_conf)
iterator = sphinx_compatibility.status_iterator(
sorted_listdir,
'Generating gallery for %s ' % build_target_dir,
length=len(sorted_listdir))
for fname in iterator:
amount_of_code, time_elapsed = generate_file_rst(fname, target_dir,
src_dir, gallery_conf)
computation_times.append((time_elapsed, fname))
new_fname = os.path.join(src_dir, fname)
intro = extract_intro(new_fname)
Expand Down Expand Up @@ -442,7 +425,7 @@ def generate_dir_rst(src_dir, target_dir, gallery_conf, seen_backrefs):
return fhindex, computation_times


def execute_code_block(code_block, example_globals,
def execute_code_block(src_file, code_block, example_globals,
block_vars, gallery_conf):
"""Executes the code block of the example file"""
time_elapsed = 0
Expand All @@ -462,9 +445,7 @@ def execute_code_block(code_block, example_globals,
# First cd in the original example dir, so that any file
# created by the example get created in this directory
os.chdir(os.path.dirname(src_file))
my_buffer = MixedEncodingStringIO()
my_stdout = Tee(sys.stdout, my_buffer)
sys.stdout = my_stdout
sys.stdout = my_stdout = MixedEncodingStringIO()

t_start = time()
# don't use unicode_literals at the top of this file or you get
Expand All @@ -474,21 +455,20 @@ def execute_code_block(code_block, example_globals,

sys.stdout = orig_stdout

my_stdout = my_buffer.getvalue().strip().expandtabs()
# raise RuntimeError
my_stdout = my_stdout.getvalue().strip().expandtabs()
if my_stdout:
stdout = CODE_OUTPUT.format(indent(my_stdout, u' ' * 4))
logger.verbose('Output from %s', src_file, color='brown')
logger.verbose(my_stdout)
os.chdir(cwd)
images_rst, fig_num = save_figures(block_vars['image_path'],
block_vars['fig_count'], gallery_conf)

except Exception:
formatted_exception = traceback.format_exc()

fail_example_warning = 80 * '_' + '\n' + \
'%s failed to execute correctly:' % src_file + \
formatted_exception + 80 * '_' + '\n'
warnings.warn(fail_example_warning)
logger.warning('%s failed to execute correctly:%s', src_file,
formatted_exception)

fig_num = 0
images_rst = codestr2rst(formatted_exception, lang='pytb')
Expand Down Expand Up @@ -588,14 +568,11 @@ def generate_file_rst(fname, target_dir, src_dir, gallery_conf):
time_elapsed = 0
block_vars = {'execute_script': execute_script, 'fig_count': 0,
'image_path': image_path_template, 'src_file': src_file}
if block_vars['execute_script']:
print('Executing file %s' % src_file)
for blabel, bcontent in script_blocks:
if blabel == 'code':
code_output, rtime = execute_code_block(bcontent,
code_output, rtime = execute_code_block(src_file, bcontent,
example_globals,
block_vars,
gallery_conf)
block_vars, gallery_conf)

time_elapsed += rtime

Expand Down Expand Up @@ -636,6 +613,6 @@ def generate_file_rst(fname, target_dir, src_dir, gallery_conf):
f.write(example_rst)

if block_vars['execute_script']:
print("{0} ran in : {1:.2g} seconds\n".format(src_file, time_elapsed))
logger.debug("%s ran in : %.2g seconds", src_file, time_elapsed)

return amount_of_code, time_elapsed
Loading