112
112
import io
113
113
import inspect
114
114
import itertools
115
+ import logging
115
116
import locale
116
117
import os
117
118
import re
123
124
# definitions, so it is safe to import from it here.
124
125
from . import cbook
125
126
from matplotlib .cbook import (
126
- _backports , mplDeprecation , dedent , get_label , sanitize_sequence )
127
+ _backports , mplDeprecation , dedent , get_label , sanitize_sequence ,
128
+ deprecated )
127
129
from matplotlib .compat import subprocess
128
130
from matplotlib .rcsetup import defaultParams , validate_backend , cycler
129
131
137
139
__version__ = str (get_versions ()['version' ])
138
140
del get_versions
139
141
142
+ _log = logging .getLogger (__name__ )
143
+
140
144
__version__numpy__ = str ('1.7.1' ) # minimum required numpy version
141
145
142
146
__bibtex__ = r"""@Article{Hunter:2007,
160
164
if not (_python27 or _python34 ):
161
165
raise ImportError ("Matplotlib requires Python 2.7 or 3.4 or later" )
162
166
167
+ if _python27 :
168
+ _log .addHandler (logging .NullHandler ())
169
+
163
170
164
171
def compare_versions (a , b ):
165
172
"return True if a is greater than or equal to b"
@@ -215,7 +222,76 @@ def _is_writable_dir(p):
215
222
"""
216
223
return os .access (p , os .W_OK ) and os .path .isdir (p )
217
224
225
+ _verbose_msg = """\
226
+ Command line argument --verbose-LEVEL is deprecated.
227
+ This functionality is now provided by the standard
228
+ python logging library. To get more (or less) logging output:"
229
+ import logging
230
+ logger = logging.getLogger('matplotlib')
231
+ logger.set_level(logging.INFO)"""
232
+
233
+
234
+ def _set_logger_verbose_level (level_str = 'silent' , file_str = 'sys.stdout' ):
235
+ """
236
+ Use a --verbose-LEVEL level to set the logging level:
218
237
238
+ """
239
+ levelmap = {'silent' : logging .WARNING , 'helpful' : logging .INFO ,
240
+ 'debug' : logging .DEBUG , 'debug-annoying' : logging .DEBUG ,
241
+ 'info' : logging .INFO , 'warning' : logging .WARNING }
242
+ # Check that current state of logger isn't already more verbose
243
+ # than the requested level. If its more verbose, then leave more
244
+ # verbose.
245
+ if level_str in levelmap :
246
+ newlev = levelmap [level_str ]
247
+ oldlev = _log .getEffectiveLevel ()
248
+ if newlev < oldlev :
249
+ _log .setLevel (newlev )
250
+ std = {
251
+ 'sys.stdout' : sys .stdout ,
252
+ 'sys.stderr' : sys .stderr ,
253
+ }
254
+ if file_str in std :
255
+ fileo = std [file_str ]
256
+ else :
257
+ fileo = sys .stdout
258
+ try :
259
+ fileo = open (file_str , 'w' )
260
+ # if this fails, we will just write to stdout
261
+ except IOError :
262
+ warnings .warn ('could not open log file "{0}"'
263
+ 'for writing. Check your '
264
+ 'matplotlibrc' .format (file_str ))
265
+ console = logging .StreamHandler (fileo )
266
+ console .setLevel (newlev )
267
+ _log .addHandler (console )
268
+
269
+
270
+ def _parse_commandline ():
271
+ """
272
+ Check for --verbose-LEVEL type command line arguments and
273
+ set logging level appropriately.
274
+ """
275
+
276
+ levels = ('silent' , 'helpful' , 'debug' , 'debug-annoying' ,
277
+ 'info' , 'warning' )
278
+
279
+ for arg in sys .argv [1 :]:
280
+ # cast to str because we are using unicode_literals,
281
+ # and argv is always str
282
+
283
+ if arg .startswith (str ('--verbose-' )):
284
+ level_str = arg [10 :]
285
+ # If it doesn't match one of ours, then don't even
286
+ # bother noting it, we are just a 3rd-party library
287
+ # to somebody else's script.
288
+ if level_str in levels :
289
+ _set_logger_verbose_level (level_str )
290
+
291
+ _parse_commandline ()
292
+
293
+
294
+ @deprecated ("2.2" , message = _verbose_msg )
219
295
class Verbose (object ):
220
296
"""
221
297
A class to handle reporting. Set the fileo attribute to any file
@@ -311,7 +387,31 @@ def ge(self, level):
311
387
return self .vald [self .level ] >= self .vald [level ]
312
388
313
389
314
- verbose = Verbose ()
390
+ def _wrap (fmt , func , level = 'INFO' , always = True ):
391
+ """
392
+ return a callable function that wraps func and reports it
393
+ output through logger
394
+
395
+ if always is True, the report will occur on every function
396
+ call; otherwise only on the first time the function is called
397
+ """
398
+ assert callable (func )
399
+
400
+ def wrapper (* args , ** kwargs ):
401
+ ret = func (* args , ** kwargs )
402
+
403
+ if (always or not wrapper ._spoke ):
404
+ lvl = logging .getLevelName (level .upper ())
405
+ _log .log (lvl , fmt % ret )
406
+ spoke = True
407
+ if not wrapper ._spoke :
408
+ wrapper ._spoke = spoke
409
+ return ret
410
+ wrapper ._spoke = False
411
+ wrapper .__doc__ = func .__doc__
412
+ return wrapper
413
+
414
+ # verbose = Verbose()
315
415
316
416
317
417
def checkdep_dvipng ():
@@ -512,7 +612,7 @@ def _create_tmp_config_dir():
512
612
return configdir
513
613
514
614
515
- get_home = verbose . wrap ('$HOME=%s' , _get_home , always = False )
615
+ get_home = _wrap ('$HOME=%s' , _get_home , always = False )
516
616
517
617
518
618
def _get_xdg_config_dir ():
@@ -601,7 +701,7 @@ def _get_configdir():
601
701
"""
602
702
return _get_config_or_cache_dir (_get_xdg_config_dir ())
603
703
604
- get_configdir = verbose . wrap ('CONFIGDIR=%s' , _get_configdir , always = False )
704
+ get_configdir = _wrap ('CONFIGDIR=%s' , _get_configdir , always = False )
605
705
606
706
607
707
def _get_cachedir ():
@@ -613,7 +713,7 @@ def _get_cachedir():
613
713
"""
614
714
return _get_config_or_cache_dir (_get_xdg_cache_dir ())
615
715
616
- get_cachedir = verbose . wrap ('CACHEDIR=%s' , _get_cachedir , always = False )
716
+ get_cachedir = _wrap ('CACHEDIR=%s' , _get_cachedir , always = False )
617
717
618
718
619
719
def _decode_filesystem_path (path ):
@@ -671,7 +771,7 @@ def _get_data_path_cached():
671
771
defaultParams ['datapath' ][0 ] = _get_data_path ()
672
772
return defaultParams ['datapath' ][0 ]
673
773
674
- get_data_path = verbose . wrap ('matplotlib data path %s' , _get_data_path_cached ,
774
+ get_data_path = _wrap ('matplotlib data path %s' , _get_data_path_cached ,
675
775
always = False )
676
776
677
777
@@ -1035,22 +1135,18 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
1035
1135
if key not in _all_deprecated ])
1036
1136
config .update (config_from_file )
1037
1137
1038
- verbose .set_level (config ['verbose.level' ])
1039
- verbose .set_fileo (config ['verbose.fileo' ])
1040
-
1041
1138
if config ['datapath' ] is None :
1042
1139
config ['datapath' ] = get_data_path ()
1043
1140
1044
1141
if "" .join (config ['text.latex.preamble' ]):
1045
- verbose . report ("""
1142
+ _log . info ("""
1046
1143
*****************************************************************
1047
1144
You have the following UNSUPPORTED LaTeX preamble customizations:
1048
1145
%s
1049
1146
Please do not ask for support with these customizations active.
1050
1147
*****************************************************************
1051
- """ % '\n ' .join (config ['text.latex.preamble' ]), 'helpful' )
1052
-
1053
- verbose .report ('loaded rc file %s' % fname )
1148
+ """ , '\n ' .join (config ['text.latex.preamble' ]))
1149
+ _log .info ('loaded rc file %s' , fname )
1054
1150
1055
1151
return config
1056
1152
@@ -1736,9 +1832,8 @@ def inner(ax, *args, **kwargs):
1736
1832
return inner
1737
1833
return param
1738
1834
1739
-
1740
- verbose .report ('matplotlib version %s' % __version__ )
1741
- verbose .report ('verbose.level %s' % verbose .level )
1742
- verbose .report ('interactive is %s' % is_interactive ())
1743
- verbose .report ('platform is %s' % sys .platform )
1744
- verbose .report ('loaded modules: %s' % list (sys .modules ), 'debug' )
1835
+ _log .info ('matplotlib version %s' , __version__ )
1836
+ #_log.info('verbose.level %s' % verbose.level)
1837
+ _log .info ('interactive is %s' , is_interactive ())
1838
+ _log .info ('platform is %s' , sys .platform )
1839
+ _log .debug ('loaded modules: %s' , list (sys .modules ))
0 commit comments