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

Skip to content

Commit 6e355a7

Browse files
committed
1) Replaced warnings.warn with either logging.warnings or cbook._warn_external.
2) Updated contributions guidelines to use cbook._warn_external.
1 parent 566bd8b commit 6e355a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+416
-351
lines changed

doc/devel/contributing.rst

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -449,29 +449,71 @@ Then they will receive messages like::
449449
Which logging level to use?
450450
~~~~~~~~~~~~~~~~~~~~~~~~~~~
451451

452-
There are five levels at which you can emit messages. `logging.critical` and
453-
`logging.error` are really only there for errors that will end the use of the
454-
library but not kill the interpreter. `logging.warning` overlaps with the
455-
`warnings` library. The `logging tutorial`_ suggests that the difference
456-
between `logging.warning` and `warnings.warn` is that `warnings.warn` should
457-
be used for things the user must change to stop the warning (typically in the
458-
source), whereas `logging.warning` can be more persistent. Moreover, note
459-
that `warnings.warn` will by default only emit a given warning *once*, whereas
460-
`logging.warning` will display the message every time it is called.
452+
There are five levels at which you can emit messages.
453+
454+
- `logging.critical` and `logging.error` are really only there for errors that
455+
will end the use of the library but not kill the interpreter.
456+
- `logging.warning` and `cbook._warn_external` are used to warn the user,
457+
see below.
458+
- `logging.info` is for information that the user may want to know if the
459+
program behaves oddly. They are not displayed by default. For instance, if
460+
an object isn't drawn because its position is ``NaN``, that can usually
461+
be ignored, but a mystified user could call
462+
``logging.basicConfig(level=logging.INFO)`` and get an error message that
463+
says why.
464+
- `logging.debug` is the least likely to be displayed, and hence can be the
465+
most verbose. "Expected" code paths (e.g., reporting normal intermediate
466+
steps of layouting or rendering) should only log at this level.
461467

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

465-
Calls to `logging.info` are not displayed by default. They are for
466-
information that the user may want to know if the program behaves oddly.
467-
For instance, if an object isn't drawn because its position is ``NaN``,
468-
that can usually be ignored, but a mystified user could call
469-
``logging.basicConfig(level=logging.INFO)`` and get an error message that
470-
says why.
471+
The `logging tutorial`_ suggests that the difference
472+
between `logging.warning` and `cbook._warn_external` (which uses
473+
`warnings.warn`) is that `cbook._warn_external` should be used for things the
474+
user must change to stop the warning (typically in the source), whereas
475+
`logging.warning` can be more persistent. Moreover, note that
476+
`cbook._warn_extrenal` will by default only emit a given warning *once* for
477+
each line of user code, whereas `logging.warning` will display the message
478+
every time it is called.
471479

472-
`logging.debug` is the least likely to be displayed, and hence can be the most
473-
verbose. "Expected" code paths (e.g., reporting normal intermediate steps of
474-
layouting or rendering) should only log at this level.
480+
By default, `warnings.warn` displays the line of code that has the `warn` call.
481+
This usually isn't more informative than the warning message itself. Therefore,
482+
Matplotlib uses `cbook._warn_external` which uses `warnings.warn`, but it goes
483+
up the stack and displays the first line of code outside of Matplotlib.
484+
For example, for the module::
485+
486+
#in my_matplotlib_module.py
487+
import warnings
488+
489+
def set_range(bottom, top):
490+
if bottom == top:
491+
warnings.warn('Attempting to set identical bottom==top')
492+
493+
494+
running the script::
495+
496+
from matplotlib import my_matplotlib_module
497+
my_matplotlib_module.set_range(0,0) #set range
498+
499+
500+
will display::
501+
502+
UserWarning: Attempting to set identical bottom==top
503+
warnings.warn('Attempting to set identical bottom==top')
504+
505+
Modifiying the module to use `cbook._warn_extermal`::
506+
507+
from matplotlib import cbook
508+
509+
def set_range(bottom, top):
510+
if bottom == top:
511+
cbook._warn_external('Attempting to set identical bottom==top')
512+
513+
and running the same script will display::
514+
515+
UserWarning: Attempting to set identical bottom==top
516+
my_matplotlib_module.set_range(0,0) #set range
475517

476518
.. _logging tutorial: https://docs.python.org/3/howto/logging.html#logging-basic-tutorial
477519

lib/matplotlib/__init__.py

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,8 @@ def _set_logger_verbose_level(level_str='silent', file_str='sys.stdout'):
244244
fileo = open(file_str, 'w')
245245
# if this fails, we will just write to stdout
246246
except IOError:
247-
warnings.warn('could not open log file "{0}"'
248-
'for writing. Check your '
249-
'matplotlibrc'.format(file_str))
247+
_log.warning('could not open log file "{0}" for writing. '
248+
'Check your matplotlibrc'.format(file_str))
250249
console = logging.StreamHandler(fileo)
251250
console.setLevel(newlev)
252251
_log.addHandler(console)
@@ -307,8 +306,9 @@ def set_level(self, level):
307306
if self._commandLineVerbose is not None:
308307
level = self._commandLineVerbose
309308
if level not in self.levels:
310-
warnings.warn('matplotlib: unrecognized --verbose-* string "%s".'
311-
' Legal values are %s' % (level, self.levels))
309+
cbook._warn_external('matplotlib: unrecognized --verbose-* '
310+
'string "%s". Legal values are %s' %
311+
(level, self.levels))
312312
else:
313313
self.level = level
314314

@@ -487,9 +487,9 @@ def checkdep_ps_distiller(s):
487487
gs_exec, gs_v = checkdep_ghostscript()
488488
if not gs_exec:
489489
flag = False
490-
warnings.warn('matplotlibrc ps.usedistiller option can not be used '
491-
'unless ghostscript 9.0 or later is installed on your '
492-
'system')
490+
_log.warning('matplotlibrc ps.usedistiller option can not be used '
491+
'unless ghostscript 9.0 or later is installed on your '
492+
'system')
493493

494494
if s == 'xpdf':
495495
pdftops_req = '3.0'
@@ -502,9 +502,9 @@ def checkdep_ps_distiller(s):
502502
pass
503503
else:
504504
flag = False
505-
warnings.warn(('matplotlibrc ps.usedistiller can not be set to '
506-
'xpdf unless xpdf-%s or later is installed on '
507-
'your system') % pdftops_req)
505+
_log.warning(('matplotlibrc ps.usedistiller can not be set to '
506+
'xpdf unless xpdf-%s or later is installed on '
507+
'your system') % pdftops_req)
508508

509509
if flag:
510510
return s
@@ -522,22 +522,22 @@ def checkdep_usetex(s):
522522

523523
if shutil.which("tex") is None:
524524
flag = False
525-
warnings.warn('matplotlibrc text.usetex option can not be used unless '
526-
'TeX is installed on your system')
525+
_log.warning('matplotlibrc text.usetex option can not be used unless '
526+
'TeX is installed on your system')
527527

528528
dvipng_v = checkdep_dvipng()
529529
if not compare_versions(dvipng_v, dvipng_req):
530530
flag = False
531-
warnings.warn('matplotlibrc text.usetex can not be used with *Agg '
532-
'backend unless dvipng-%s or later is installed on '
533-
'your system' % dvipng_req)
531+
_log.warning('matplotlibrc text.usetex can not be used with *Agg '
532+
'backend unless dvipng-%s or later is installed on '
533+
'your system' % dvipng_req)
534534

535535
gs_exec, gs_v = checkdep_ghostscript()
536536
if not compare_versions(gs_v, gs_req):
537537
flag = False
538-
warnings.warn('matplotlibrc text.usetex can not be used unless '
539-
'ghostscript-%s or later is installed on your system'
540-
% gs_req)
538+
_log.warning('matplotlibrc text.usetex can not be used unless '
539+
'ghostscript-%s or later is installed on your system'
540+
% gs_req)
541541

542542
return flag
543543

@@ -954,17 +954,17 @@ def _rc_params_in_file(fname, fail_on_error=False):
954954
tup = strippedline.split(':', 1)
955955
if len(tup) != 2:
956956
error_details = _error_details_fmt % (cnt, line, fname)
957-
warnings.warn('Illegal %s' % error_details)
957+
_log.warning('Illegal %s' % error_details)
958958
continue
959959
key, val = tup
960960
key = key.strip()
961961
val = val.strip()
962962
if key in rc_temp:
963-
warnings.warn('Duplicate key in file "%s", line #%d' %
963+
_log.warning('Duplicate key in file "%s", line #%d' %
964964
(fname, cnt))
965965
rc_temp[key] = (val, line, cnt)
966966
except UnicodeDecodeError:
967-
warnings.warn(
967+
_log.warning(
968968
('Cannot decode configuration file %s with '
969969
'encoding %s, check LANG and LC_* variables')
970970
% (fname, locale.getpreferredencoding(do_setlocale=False) or
@@ -983,8 +983,8 @@ def _rc_params_in_file(fname, fail_on_error=False):
983983
config[key] = val # try to convert to proper type or skip
984984
except Exception as msg:
985985
error_details = _error_details_fmt % (cnt, line, fname)
986-
warnings.warn('Bad val "%s" on %s\n\t%s' %
987-
(val, error_details, msg))
986+
_log.warning('Bad val "%s" on %s\n\t%s' %
987+
(val, error_details, msg))
988988

989989
for key, (val, line, cnt) in rc_temp.items():
990990
if key in defaultParams:
@@ -995,8 +995,8 @@ def _rc_params_in_file(fname, fail_on_error=False):
995995
config[key] = val # try to convert to proper type or skip
996996
except Exception as msg:
997997
error_details = _error_details_fmt % (cnt, line, fname)
998-
warnings.warn('Bad val "%s" on %s\n\t%s' %
999-
(val, error_details, msg))
998+
_log.warning('Bad val "%s" on %s\n\t%s' %
999+
(val, error_details, msg))
10001000
elif key in _deprecated_ignore_map:
10011001
version, alt_key = _deprecated_ignore_map[key]
10021002
cbook.warn_deprecated(
@@ -1338,10 +1338,9 @@ def use(arg, warn=True, force=False):
13381338
# If we are going to force the switch, never warn, else, if warn
13391339
# is True, then direct users to `plt.switch_backend`
13401340
if (not force) and warn:
1341-
warnings.warn(
1341+
cbook._warn_external(
13421342
("matplotlib.pyplot as already been imported, "
1343-
"this call will have no effect."),
1344-
stacklevel=2)
1343+
"this call will have no effect."))
13451344

13461345
# if we are going to force switching the backend, pull in
13471346
# `switch_backend` from pyplot. This will only happen if
@@ -1421,7 +1420,7 @@ def _init_tests():
14211420
from matplotlib import ft2font
14221421
if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or
14231422
ft2font.__freetype_build_type__ != 'local'):
1424-
warnings.warn(
1423+
_log.warning(
14251424
"Matplotlib is not built with the correct FreeType version to run "
14261425
"tests. Set local_freetype=True in setup.cfg and rebuild. "
14271426
"Expect many image comparison failures below. "
@@ -1430,9 +1429,7 @@ def _init_tests():
14301429
"Freetype build type is {2}local".format(
14311430
LOCAL_FREETYPE_VERSION,
14321431
ft2font.__freetype_version__,
1433-
"" if ft2font.__freetype_build_type__ == 'local' else "not "
1434-
)
1435-
)
1432+
"" if ft2font.__freetype_build_type__ == 'local' else "not "))
14361433

14371434
try:
14381435
import pytest
@@ -1762,12 +1759,12 @@ def inner(ax, *args, data=None, **kwargs):
17621759
elif label_namer in kwargs:
17631760
kwargs['label'] = get_label(kwargs[label_namer], label)
17641761
else:
1765-
warnings.warn(
1762+
cbook._warn_external(
17661763
"Tried to set a label via parameter %r in func %r but "
1767-
"couldn't find such an argument.\n"
1768-
"(This is a programming error, please report to "
1769-
"the Matplotlib list!)" % (label_namer, func.__name__),
1770-
RuntimeWarning, stacklevel=2)
1764+
"couldn't find such an argument.\n(This is a "
1765+
"programming error, please report to the Matplotlib "
1766+
"list!)" % (label_namer, func.__name__),
1767+
RuntimeWarning)
17711768
return func(ax, *args, **kwargs)
17721769

17731770
inner.__doc__ = _add_data_doc(inner.__doc__,

lib/matplotlib/_constrained_layout.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747

4848
import numpy as np
4949
import logging
50-
import warnings
50+
import matplotlib.cbook as cbook
5151

5252
import matplotlib._layoutbox as layoutbox
5353

@@ -153,9 +153,9 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
153153
if gs._layoutbox is not None:
154154
gss.add(gs)
155155
if len(gss) == 0:
156-
warnings.warn('There are no gridspecs with layoutboxes. '
157-
'Possibly did not call parent GridSpec with the figure= '
158-
'keyword')
156+
cbook._warn_external('There are no gridspecs with layoutboxes. '
157+
'Possibly did not call parent GridSpec with the'
158+
' figure= keyword')
159159

160160
if fig._layoutbox.constrained_layout_called < 1:
161161
for gs in gss:
@@ -221,8 +221,8 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
221221
# so this does the same w/o zeroing layout.
222222
ax._set_position(newpos, which='original')
223223
else:
224-
warnings.warn('constrained_layout not applied. At least '
225-
'one axes collapsed to zero width or height.')
224+
cbook._warn_external('constrained_layout not applied. At least '
225+
'one axes collapsed to zero width or height.')
226226

227227

228228
def _make_ghost_gridspec_slots(fig, gs):

lib/matplotlib/artist.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import inspect
44
import re
55
import warnings
6+
import logging
67

78
import numpy as np
89

@@ -12,6 +13,8 @@
1213
from .transforms import (Bbox, IdentityTransform, Transform, TransformedBbox,
1314
TransformedPatchPath, TransformedPath)
1415

16+
_log = logging.getLogger(__name__)
17+
1518

1619
def allow_rasterization(draw):
1720
"""
@@ -400,7 +403,7 @@ def contains(self, mouseevent):
400403
"""
401404
if callable(self._contains):
402405
return self._contains(self, mouseevent)
403-
warnings.warn("'%s' needs 'contains' method" % self.__class__.__name__)
406+
_log.warning("'%s' needs 'contains' method" % self.__class__.__name__)
404407
return False, {}
405408

406409
def set_contains(self, picker):
@@ -850,7 +853,8 @@ def set_rasterized(self, rasterized):
850853
rasterized : bool or None
851854
"""
852855
if rasterized and not hasattr(self.draw, "_supports_rasterization"):
853-
warnings.warn("Rasterization of '%s' will be ignored" % self)
856+
cbook._warn_external(
857+
"Rasterization of '%s' will be ignored" % self)
854858

855859
self._rasterized = rasterized
856860

lib/matplotlib/axes/_axes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4624,8 +4624,9 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
46244624
# Set normalizer if bins is 'log'
46254625
if bins == 'log':
46264626
if norm is not None:
4627-
warnings.warn("Only one of 'bins' and 'norm' arguments can be "
4628-
"supplied, ignoring bins={}".format(bins))
4627+
cbook._warn_external("Only one of 'bins' and 'norm' "
4628+
"arguments can be supplied, ignoring "
4629+
"bins={}".format(bins))
46294630
else:
46304631
norm = mcolors.LogNorm()
46314632
bins = None

0 commit comments

Comments
 (0)