Skip to content

[MRG] Replace verbose class with standard logging library #9313

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 1 commit into from
Nov 12, 2017

Conversation

jklymak
Copy link
Member

@jklymak jklymak commented Oct 8, 2017

PR Summary

This replaces Matplotlib's Verbose class and calls with the standard logging library. Hopefully this will lead to more debugging information and better integration with downstream packages.

See #9302 and discussion therein.

How to use:

For the end-user:

The old command-line --verbose-debug and --verbose-helpful are still respected (and --verbose-info was even added). These are likely to be deprecated but are not for now.

Better is for a script to load and configure the logging library before importing matplotlib:

At its most basic:

import logging
logging.basicConfig(level=logging.DEBUG)
import matplotlib.pyplot as plt

in the header should do it. A slightly more useful formatting will give line numbers:

import logging
Format = '%(name)s:%(lineno)5d - %(levelname)s - %(message)s'
logging.basicConfig(level=logging.DEBUG,
                        format=Format)
import matplotlib.pyplot as plt

The resulting console output will be something like:

matplotlib.backends:   89 - INFO - backend MacOSX version unknown
matplotlib.font_manager: 1335 - INFO - findfont: Matching :family=sans-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0 to Bitstream Vera Sans ('/opt/X11/share/fonts/TTF/Vera.ttf') with score of 0.050000
matplotlib.text:  768 - INFO - x and y are not finite values for text string 'boo!'.  Not rendering text.
matplotlib.text:  768 - INFO - x and y are not finite values for text string 'boo!'.  Not rendering text.

which is then pretty easily grep-able to find debug info in particular modules.

For the module writer

At the top of the module, you need to import logging. Then calls like

log = logging.getLogger(__name__)
log.info('Here is some information')
log.debug('Here is some more detailed information')

will log to a logger named matplotlib.yourmodulename. Theoretically, getLogger is not too expensive, so you need not save the logger for each class (and you don't need to instantiate it in any way other than a call to getLogger somewhere).

I've used the name log throughout the code, which maybe is a problematic choice. One can use any name you want if this clashes in your module's namespace.

Which logging level to use?

There are five logging levels. logging.critical() and logging.error() are really only there for errors that will end the use of the library but not kill the interpreter. WARNING overlaps with the warning library. The logging tutorial has suggested differentiation between logging.warning() and warning.warn().

By default, logging displays all log messages at levels higher than logging.WARNING to sys.stderr.

logging.info() is not displayed by default. Its for information that the user may want to know if the program behaves oddly. For instance, if an object isn't drawn because its position is NaN, that can usually be ignored, but a mystified user could set logging.basicConfig(level=logging.INFO) and if the module writer is kind get an error message that says why.

logging.debug() is the least likely to be displayed, and hence can be the most verbose.

Fate of --verbose and the rcParams...

The --verbose-debug and --verbose-helpful command line options are still handled and set
logging.basicConfig(level=logging.DEBUG) and ``logging.basicConfig(level=logging.INFO)` respectively.

The entries in matplotlibrc are still respected by the same logic (verbose.level and verbose.fileo). However, they are on the deprecated list and those entries have been removed from the matplotlibrc.template.

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@jklymak jklymak added this to the 2.2 (next feature release) milestone Oct 8, 2017
@jklymak jklymak changed the title Replace Verbose with standard Logging library [WIP] Replace verbose class with standard logging library Oct 8, 2017
@@ -1442,7 +1445,7 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble,
latexfile = latexfile.replace("~", "\\string~")
command = [str("latex"), "-interaction=nonstopmode",
'"%s"' % latexfile]
verbose.report(command, 'debug')
log.debug(command)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use log.debug('%s', command) (throughout) so as not to crash if command has the bad idea of including a %. See sphinx-doc/sphinx#4070 for a similar issue (except that they mangled the fix :-/).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can see this has an advantage. OTOH, there is lots of this kind of formatting that was being passed to verbose. I don't mind fixing the easy cases, but there are also cases like:

log.info('figure size (inches) has been adjusted '
                               'from %s x %s to %s x %s' % (wo, ho, w, h))

I tested this, and its not as simple as:

log.info('figure size (inches) has been adjusted '
                               'from %s x %s to %s x %s', (wo, ho, w, h))

which fails.

More importantly, I'm concerned that by redoing all these I'll screw something up. These aren't the easiest parts of the code to debug since the tests don't get run with the logging turned on.

For now, I'll fix the easy one-%s cases, but not the more complicated formatting.

if "".join(config['text.latex.preamble']):
verbose.report("""
log.info("""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard way is to do

log.info("format_string %s", args)

instead of

log.info("format string %s" % args)

Note that the latter form will raise an exception if args has the bad idea of including a % (see comment below for more details).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional point of information: the reason the logging module uses a format string followed by arguments is that this means the string interpolation is done only if the logging level is such that the result will actually be used. In other words, it is a performance optimization.

@jklymak jklymak changed the title [WIP] Replace verbose class with standard logging library [WIP: Needs docs] Replace verbose class with standard logging library Oct 8, 2017
@jklymak jklymak requested review from tacaswell and anntzer October 8, 2017 19:43
@jklymak
Copy link
Member Author

jklymak commented Oct 8, 2017

Asking for functionality reviews before I write up docs as they will need to be changed in a number of places if this is the way we want to go forward.

output:
`import logging`
`logger=logging.getLogger('matplotlib')`
`logger.set_level(logging.INFO)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import logging
logging.getLogger('matplotlib').setLevel(logging.INFO)

yes it's camelcase
and if you want to keep it over three lines, spaces around =

"""
levelmap = {'silent': logging.WARNING, 'helpful': logging.INFO,
'debug': logging.DEBUG, 'debug-annoying': logging.DEBUG,
'info': logging.INFO, 'warning': logging.warning}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging.WARNING

fileo = open(file_str, 'w')
# if this fails, we will just write to stdout
except IOError:
warning.warn('could not open log file "{0}"'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warnings

# if this fails, we will just write to stdout
except IOError:
warning.warn('could not open log file "{0}"'
'for writing.\nCheck your '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend not to prefer embedding newlines into this kind of messages because you never know what the width of the console is going to be anyways. Not a big deal though.


for arg in sys.argv[1:]:
# cast to str because we are using unicode_literals,
# and argv is always str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need the cast? On Py2 the str will just happily check for startswith against unicode; on Py3 everything is str.
If you do need the cast I'd just write for arg in map(str, sys.argv[1:])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might a 2.6 hold over?

This works as expected on as far back as 2.7.3 (the earliest version conda had easily available).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works with 2.6.8 as well, I do wonder how far back this goes...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to leave this in as I just copied from old code and don't understand the cast. Feel free to tell me the proper way to do it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also suggest leaving out the cast and the comment block that goes with it.

output through logger

if always is True, the report will occur on every function
call; otherwise only on the first time the function is called
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we ever use always=True so we may as well drop that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole class is deprecated, so...

@@ -760,7 +858,8 @@ def gen_candidates():

_deprecated_ignore_map = {}

_obsolete_set = {'text.dvipnghack', 'legend.isaxes'}
_obsolete_set = {'text.dvipnghack', 'legend.isaxes', 'verbose.level',
'verbose.fileo'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you deprecated them? I the log level should stay configurable from the mplrc?

@@ -3,7 +3,7 @@

import six

import os, sys
import os, sys, loging
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tyop

Copy link
Contributor

@anntzer anntzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's bunch of minor edits here and there (haven't listed them all) and I think the logger level should stay configurable from the matplotlibrc, but the general approach looks good to me.

@anntzer
Copy link
Contributor

anntzer commented Oct 9, 2017

WARNING overlaps with the warning library. The logging tutorial has suggested differentiation between logging.warning() and warning.warn().

The main point that must be paid attention to is that by default, a given warning.warn (same content and emitted from the same line of code) will only be shown once (it is then stored in a cache and later calls will be suppressed), whereas a logger.warning will be shown every time.
logger.warning is also more easy to configure (together with all other logging settings) so I would prefer defaulting to using logger.warning, except for things that we explicitly want to make harder to suppress...

@jklymak
Copy link
Member Author

jklymak commented Oct 9, 2017

@anntzer Thanks so much for the comments. I'll try and address (though quite a few were just copied over, rather than new). Your larger points:

More than happy to walk back the changes and deprecation warnings on the matplotlibrc. I personally think it could cause more confusion than not, but maybe thats also how I've implemented it.

Right now, it takes the most verbose of a) an already instantiated matplotlib logger (i.e by the user in their code), b) the command-line option and c) matplotlibrc file. I could easily modify that if we aren't planning to deprecate the matplotlibrc pathway. If we did that, I'd suggest that whatever is set in the matplotlibrc is ignored if either the logger has already been instantiated of --verbose-LEVEL is used. I'd probably keep the behaviour of choosing the most verbose between the command line and programatic invocation since they are both being actively sought by the user.

I think there is also a problem calling all these things verbose when they are now explicitly calling logging. But maybe thats a documentation issue.

WRT guidance about what level of verbosity folks should use, and choices between warnings.warn and logging.warning, I'm way too inexperienced to make that call. I wrote what I wrote above to start discussion, but it should really be the core developers who make that sort of policy. (I'm also not volunteering to go through the code and decide what should get logging.warning versus warnings.warn! I imagine thats a fix-as-we-go sort of thing, and again, I wouldn't presume to know what the right behaviour is)

@anntzer
Copy link
Contributor

anntzer commented Oct 9, 2017

I think we can leave the calls to warnings.warn as they are for now and change them to logger.warning in a piecemeal fashion whereever appropriate.
I think properly documenting that verbose is now controlling the mplrc is the easiest way to go.
I think the order of priority should be from low to high: matplotlibrc, --verbose-foo, explicitly configured logger. The idea being that --verbose-foo is easier to set on an interactive basis than matplotlibrc, but if one already bothered setting up an explicitly configured logger, then adding the code to configure the level yourself should not be a big deal...

@efiring
Copy link
Member

efiring commented Oct 9, 2017

I will try to give this a close look ASAP. Thank you for taking this on; it's definitely the direction we need to go.

@jklymak
Copy link
Member Author

jklymak commented Oct 9, 2017

@efiring That'd be great. Did you want me to factor in @anntzer review first?

@efiring
Copy link
Member

efiring commented Oct 9, 2017

Yes, please go ahead with @anntzer's suggestions.

else:
w, h = self.fig.get_size_inches()
verbose.report('frame size in pixels is %s x %s' % self.frame_size,
level='debug')
log.info('frame size in pixels is %s x %s' % self.frame_size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to change the lever on this one (makes sense to match the one just above)

@tacaswell
Copy link
Member

Without minimizing the amount of work done, this is less invasive change than I expected!

I definitely think that this is the right way to go. On a quick read, the mapping between the verbose levels and the logging level makes sense.

Agree with @anntzer to not touch warnings.warn for now. Most of them are deprecation, not run time, warnings and we want to make them hard to suppress.

A while ago I also wrote up notes on loggers (https://github.com/scikit-beam/scikit-beam/blob/dd8625baa22c886601d51ff0c6fea0aee01c86cb/doc/resource/dev_guide/logging.rst ) which may or may not be a useful reference.

@jklymak
Copy link
Member Author

jklymak commented Oct 11, 2017

@anntzer Above you proposed to prioritze:

  1. code-instantiation of logger
  2. command-line --verbose-LEVEL (but deprecate?)
  3. maplotlibrc verbose.level and verbose.fileo.

The problem is I don't think there is anyway from within matplotlib.__init__ to know that the user has explictly done logger = logging.getLogger('matplotlib').logger.set_level(logging.WARNING) (you can check for other levels) because it is the default.

If its true that we can't detect that the user has specified this in their code, then that becomes very confusing if we say that the coded logger will take priority unless it is set to WARNING and then we will look at the command line or matplotlibrc.

I am personally against this being set at all in the matplotlibrc. How the library interacts with the interpreter doesn't seem like a role for the configuration file.

My proposal would be:

  1. the level is the default logging.WARNING.
  2. the greater of the command-line argument and the explicitly coded argument.
  3. the matplotlibrc is deprecated.

If we want to keep the matplotlibrc, then I'd suggest the greater of the three pathways.

This is probably just my bias, as I think I've dug out my matplotlibrc maybe twice in the 5 years I've used matplotlib ;-)

@jklymak
Copy link
Member Author

jklymak commented Oct 11, 2017

@tacaswell Not minimizing the amount of work at all. It was pretty minimal. Which I think is somewhat unfortunate, because it means people are avoiding putting debugging into their code. Not sure if this will change that, and maybe there are good reasons not to spam the logger if you are doing something that requires high performance.

@anntzer
Copy link
Contributor

anntzer commented Oct 11, 2017

@anntzer Above you proposed to prioritze:

code-instantiation of logger
command-line --verbose-LEVEL (but deprecate?)
maplotlibrc verbose.level and verbose.fileo.
The problem is I don't think there is anyway from within matplotlib.init to know that the user has explictly done logger = logging.getLogger('matplotlib').logger.set_level(logging.WARNING) (you can check for other levels) because it is the default.

If its true that we can't detect that the user has specified this in their code, then that becomes very confusing if we say that the coded logger will take priority unless it is set to WARNING and then we will look at the command line or matplotlibrc.

"matplotlib" in logging.Logger.manager.loggerDict (strictly speaking it only checks whether the logger already exists, but that seems close enough -- why would the user instantiate a logger otherwise?).

I am personally against this being set at all in the matplotlibrc. How the library interacts with the interpreter doesn't seem like a role for the configuration file.

My proposal would be:

the level is the default logging.WARNING.
the greater of the command-line argument and the explicitly coded argument.
the matplotlibrc is deprecated.
If we want to keep the matplotlibrc, then I'd suggest the greater of the three pathways.

I think I'm +0.5 on keeping matplotlibrc support, but am happy to hear input from others.

@jklymak
Copy link
Member Author

jklymak commented Oct 11, 2017

Awesome! I’m fine with instantiation trumps all if that is the route to go. If anyone else has an opinion let me know. If not I’ll implement @anntzers preferred method.

@jklymak
Copy link
Member Author

jklymak commented Oct 11, 2017

Meh. If we set logging.basicConfig(level=logging.WARNING) (which is the easiest way to invoke logging) then logging.Logger.manager.loggerDict stays empty, but the root logger is changed.

So, given that we can't tell if the root logger has been set (I don't think), what do we want to do?

Using logging for debug messages
--------------------------------

Matplotlib uses the standard python logging_ library to write verbose
Copy link
Contributor

@anntzer anntzer Nov 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have an intersphinx mapping (https://github.com/matplotlib/matplotlib/blob/master/doc/conf.py#L95) to the stdlib so you can (should) just write

`logging`
`print`
`warnings.warn`

etc. and they will link to the corresponding entries in the stdlib docs

Which logging level to use?
~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are five logging levels. :func:`logging.critical()` and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the level is logging.CRITICAL, not logging.critical.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, but I want to refer to the functions. Changed to There are five levels at which you can emit messages.


import matplotlib.pyplot as plt

Note that if you want to use logging_ in your own code, but do not
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above re: intersphinx

@jklymak jklymak force-pushed the logging branch 2 times, most recently from 6b3edf1 to d77e94f Compare November 2, 2017 00:51
.appveyor.yml Outdated
@@ -144,7 +144,7 @@ after_test:
# After the tests were a success, build packages (wheels and conda)

# Build the wheel with the static libs
# Hide the output, the copied files really clutter the build log...
# Hide the output, the copied files really clutter the build_log...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave this as it was?

There are five levels at which you can emit messages.
`logging.critical` and `logging.error`
are really only there for errors that will end the use of the library but
not kill the interpreter. :`logging.warning()` overlaps with the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spurious colon

_verbose_msg = """\
Command line argument --verbose-LEVEL is deprecated.
This functionality is now provided by the standard
python logging library. To get more (or less) logging output:"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spurious quote

verbose.report('platform is %s' % sys.platform)
verbose.report('loaded modules: %s' % list(sys.modules), 'debug')
_log.info('matplotlib version %s', __version__)
#_log.info('verbose.level %s' % verbose.level)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just remove it?

@@ -650,7 +640,8 @@ def _args(self):
'-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format,
'-r', str(self.fps)]
# Logging is quieted because subprocess.PIPE has limited buffer size.
if not verbose.ge('debug'):

if not (_log.getEffectiveLevel() >= logging.DEBUG):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aka < DEBUG? :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that works!

@@ -48,6 +49,8 @@
TransformedBbox)
from matplotlib.backend_bases import NonGuiException

_log = logging.getLogger(__name__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can do without? (and without the import)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stuck it in there because I have a PR that will need it anyways ;-) I actually think this should be at the top of most modules so folks use the debugging. I appreciate there may be a small performance hit on some intensive modules, but hopefully not a big deal

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I agree with changing some of the warnings.warn to logging in animation, but I'll leave it to someone who uses that to comment.


will log to a logger named ``matplotlib.yourmodulename``.

If an end-user of your module sets up `logging` to display at levels
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of Matplotlib

import logging
Format = '%(name)s:%(lineno)5d - %(levelname)s - %(message)s'
logging.basicConfig(level=logging.DEBUG,
format=Format)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much indent.

more verbose than `logger.WARNING` in their code as follows::

import logging
Format = '%(name)s:%(lineno)5d - %(levelname)s - %(message)s'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No capitalization for variables; fmt if you want to avoid format.

~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are five levels at which you can emit messages.
`logging.critical` and `logging.error`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use bullet list?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave as is for now, but am happy for tweaks later...

* You can get very helpful debugging output from matlotlib by running your
script with a ``verbose-helpful`` or ``--verbose-debug`` flags and posting
the verbose output the lists::
* You can get helpful debugging output from matlotlib by using the logging_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matplotlib

@@ -3,7 +3,11 @@

import six

import os, sys, warnings
import logging

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra blank line.

"not enabled the matplotlib 'text.latex.unicode' "
"rcParam.", 'helpful')
_log.info("You are using unicode and latex, but have "
"not enabled the matplotlib 'text.latex.unicode' "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more space.


command = [str('dvips'), '-q', '-R0', '-o', os.path.basename(psfile),
os.path.basename(dvifile)]
verbose.report(command, 'debug')
_log.debug(command)
Copy link
Member

@QuLogic QuLogic Nov 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you convert the one above to use '%s' and not this one (or the rest of them)?

@@ -21,6 +21,7 @@
unicode_literals)

import six
import logging
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be in the next block.

@@ -17,17 +17,20 @@
from six.moves.urllib.request import urlopen

import datetime
import logging
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this file is deprecated, you may want to send these changes to the new upstream.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean? Whatever is replacing this file? Not sure what that is!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh mpl_finance? Hmmm

Using logging for debug messages
--------------------------------

Matplotlib uses the standard python `logging` library to write verbose
Copy link
Member Author

@jklymak jklymak Nov 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake

Change verbose to standard logging library

PEP8 fixes and formatting of log messages @anntzer

PEP8 fixes and formatting of log messages @anntzer

Small fixes as suggested by @aantzer and @tacaswell

Documentation

Fix on merge

Number small fixes

Small fix for docs

Small fix for error in animate.py

fixed import order and small doc fix

Small doc fix

Changed log. to _log.

Fix on merge

Number small fixes

Small fix for docs

Small fix for error in animate.py

fixed import order and small doc fix

Small doc fix

Changed log. to _log.

Changed log. to _log.

fixed fonts

gah

gah

gah

gah

gah

gah

PEP8 doc fix

revert _base.py

fix missing _log

Fixes for @efiring

Fixes for @anntzer

minor

Doc link fixes @anntzer

Small doc change

Many small changes, thanks @QuLogic and @anntzer

Link error docs
@jklymak
Copy link
Member Author

jklymak commented Nov 12, 2017

master rebase

Copy link
Contributor

@anntzer anntzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @efiring that this is good enough to go in as is.

@anntzer anntzer merged commit 477c1dc into matplotlib:master Nov 12, 2017
@jklymak jklymak deleted the logging branch November 13, 2017 02:08
@tacaswell
Copy link
Member

Sweet! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants