[Apply SF patch #504943]

This patch makes it possible to pass Warning instances as the first
argument to warnings.warn. In this case the category argument
will be ignored. The message text used will be str(warninginstance).
This commit is contained in:
Walter Dörwald 2002-03-21 10:38:40 +00:00
parent 047c05ebc4
commit b25c2b0a4a
3 changed files with 23 additions and 6 deletions

View File

@ -145,7 +145,10 @@ message to \code{sys.stderr}).
\begin{funcdesc}{warn}{message\optional{, category\optional{, stacklevel}}} \begin{funcdesc}{warn}{message\optional{, category\optional{, stacklevel}}}
Issue a warning, or maybe ignore it or raise an exception. The Issue a warning, or maybe ignore it or raise an exception. The
\var{category} argument, if given, must be a warning category class \var{category} argument, if given, must be a warning category class
(see above); it defaults to \exception{UserWarning}. This function (see above); it defaults to \exception{UserWarning}. Alternatively
\var{message} can be a \exception{Warning} instance, in which case
\var{category} will be ignore and \code{message.__class__} will be used.
In this case the message text will be \code{str(message)}. This function
raises an exception if the particular warning issued is changed raises an exception if the particular warning issued is changed
into an error by the warnings filter see above. The \var{stacklevel} into an error by the warnings filter see above. The \var{stacklevel}
argument can be used by wrapper functions written in Python, like argument can be used by wrapper functions written in Python, like
@ -169,6 +172,9 @@ filename and line number, and optionally the module name and the
registry (which should be the \code{__warningregistry__} dictionary of registry (which should be the \code{__warningregistry__} dictionary of
the module). The module name defaults to the filename with \code{.py} the module). The module name defaults to the filename with \code{.py}
stripped; if no registry is passed, the warning is never suppressed. stripped; if no registry is passed, the warning is never suppressed.
\var{message} must be a string and \var{category} a subclass of
\exception{Warning} or \var{message} may be a \exception{Warning} instance,
in which case \var{category} will be ignored.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{showwarning}{message, category, filename, \begin{funcdesc}{showwarning}{message, category, filename,

View File

@ -11,6 +11,9 @@ onceregistry = {}
def warn(message, category=None, stacklevel=1): def warn(message, category=None, stacklevel=1):
"""Issue a warning, or maybe ignore it or raise an exception.""" """Issue a warning, or maybe ignore it or raise an exception."""
# Check if message is already a Warning object
if isinstance(message, Warning):
category = message.__class__
# Check category argument # Check category argument
if category is None: if category is None:
category = UserWarning category = UserWarning
@ -49,14 +52,20 @@ def warn_explicit(message, category, filename, lineno,
module = module[:-3] # XXX What about leading pathname? module = module[:-3] # XXX What about leading pathname?
if registry is None: if registry is None:
registry = {} registry = {}
key = (message, category, lineno) if isinstance(message, Warning):
text = str(message)
category = message.__class__
else:
text = message
message = category(message)
key = (text, category, lineno)
# Quick test for common case # Quick test for common case
if registry.get(key): if registry.get(key):
return return
# Search the filters # Search the filters
for item in filters: for item in filters:
action, msg, cat, mod, ln = item action, msg, cat, mod, ln = item
if (msg.match(message) and if (msg.match(text) and
issubclass(category, cat) and issubclass(category, cat) and
mod.match(module) and mod.match(module) and
(ln == 0 or lineno == ln)): (ln == 0 or lineno == ln)):
@ -68,11 +77,11 @@ def warn_explicit(message, category, filename, lineno,
registry[key] = 1 registry[key] = 1
return return
if action == "error": if action == "error":
raise category(message) raise message
# Other actions # Other actions
if action == "once": if action == "once":
registry[key] = 1 registry[key] = 1
oncekey = (message, category) oncekey = (text, category)
if onceregistry.get(oncekey): if onceregistry.get(oncekey):
return return
onceregistry[oncekey] = 1 onceregistry[oncekey] = 1
@ -80,7 +89,7 @@ def warn_explicit(message, category, filename, lineno,
pass pass
elif action == "module": elif action == "module":
registry[key] = 1 registry[key] = 1
altkey = (message, category, 0) altkey = (text, category, 0)
if registry.get(altkey): if registry.get(altkey):
return return
registry[altkey] = 1 registry[altkey] = 1

View File

@ -70,6 +70,8 @@ Library
- distutils bdist commands now offer a --skip-build option. - distutils bdist commands now offer a --skip-build option.
- warnings.warn now accepts a Warning instance as first argument.
Tools/Demos Tools/Demos
Build Build