[Python-checkins] CVS: python/nondist/peps pep-0230.txt,1.2,1.3
Guido van Rossum
python-dev@python.org
Thu, 7 Dec 2000 13:52:16 -0800
Update of /cvsroot/python/python/nondist/peps
In directory slayer.i.sourceforge.net:/tmp/cvs-serv25254
Modified Files:
pep-0230.txt
Log Message:
Revised version, completing a bunch of things that weren't resolved
before. The implementation was removed from the PEP, it's now in the
SF patch manager; I'm pretty happy with it! :-)
Index: pep-0230.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0230.txt,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** pep-0230.txt 2000/12/07 17:38:50 1.2
--- pep-0230.txt 2000/12/07 21:52:14 1.3
***************
*** 191,350 ****
! TO DO
! - There should be a function sys.insertwarningfilter(message,
! category, filename, lineno) that inserts items into the warnings
! filter after some sanity checking.
! - There should be command line options to specify the most common
! filtering actions, which I expect to include at least:
! - suppress all warnings
! - suppress a particular warning message everywhere
! - suppress all warnings in a particular module
! - turn all warnings into exceptions
! Implementation
! Here is a mostly functional implementation:
! """Prototype implementation of sys.warn() and related stuff."""
! import sys, re, linecache, getopt
! class Warning(Exception):
! """Base class for warning categories.
! All warning categories must be subclasses of this.
! """
! pass
!
! class UserWarning(Warning):
! """Base class for warnings generated by user code."""
! pass
!
! class DeprecationWarning(Warning):
! """Base class for warnings about deprecated features."""
! pass
!
! class SyntaxWarning(Warning):
! """Base class for warnings about dubious syntax."""
! pass
!
! defaultaction = "default"
! filter = []
! onceregistry = {}
!
! def warn(message, category=None, level=1):
! """Issue a warning, or maybe ignore it or raise an exception."""
! # Check category argument
! if category is None:
! category = UserWarning
! assert issubclass(category, Warning)
! # Get context information
! caller = sys._getframe(level)
! globals = caller.f_globals
! lineno = caller.f_lineno
! module = globals['__name__']
! filename = globals.get('__file__')
! if not filename:
! if module == "__main__":
! filename = sys.argv[0]
! if not filename:
! filename = module
! # Quick test for common case
! registry = globals.setdefault("__warningregistry__", {})
! key = (message, category, lineno)
! if registry.get(key):
! return
! # Search the filter
! for msg, cat, mod, ln, action in filter:
! if (re.match(msg, message) and
! issubclass(category, cat) and
! re.match(mod, module) and
! (ln == 0 or lineno == ln)):
! break
! else:
! action = defaultaction
! # Early exit actions
! if action == "ignore":
! registry[key] = 1
! return
! if action == "error":
! raise category(message)
! # Other actions
! if action == "once":
! registry[key] = 1
! oncekey = (message, category)
! if onceregistry.get(oncekey):
! return
! onceregistry[oncekey] = 1
! elif action == "always":
! pass
! elif action == "module":
! registry[key] = 1
! altkey = (message, category, 0)
! if registry.get(altkey):
! return
! registry[altkey] = 1
! elif action == "default":
! registry[key] = 1
! else:
! # Unrecognized actions are errors
! raise RuntimeError(
! "Unrecognized action (%s) in warnings.filter:\n %s" %
! (`action`, str((cat, msg, mod, ln, action))))
! # Print message and context
! showwarning(message, category, filename, lineno)
!
! def showwarning(message, category, filename, lineno):
! print >>sys.stderr, "%s:%s: %s: %s" % (filename, lineno,
! category.__name__, message)
! line = linecache.getline(filename, lineno).strip()
! if line:
! print >>sys.stderr, " " + line
!
! def setupfilter(args):
! """Set up the warnings filter based upon command line options.
!
! Return remaining command line arguments.
! Raise getopt.error if an unrecognized option is found.
! """
! opts, args = getopt.getop(args, "")
! return args
!
! # Self-test
!
! def _test():
! hello = "hello world"
! warn(hello)
! warn(hello, UserWarning)
! warn(hello, DeprecationWarning)
! for i in range(3):
! warn(hello)
! filter.append(("", Warning, "", 0, "error"))
! try:
! warn(hello)
! except Exception, msg:
! print "Caught", msg.__class__.__name__ + ":", msg
! else:
! print "No exception"
! filter[:] = []
! filter.append(("", Warning, "", 0, "booh"))
! try:
! warn(hello)
! except Exception, msg:
! print "Caught", msg.__class__.__name__ + ":", msg
! else:
! print "No exception"
!
! if __name__ == "__main__":
! args = setupfilter(sys.argv[1:])
! _test()
--- 191,334 ----
! API For Manipulating Warning Filters
! sys.filterwarnings(message, category, module, lineno, action)
! This checks the types of the arguments and inserts them as a tuple
! in front of the warnings filter.
! sys.resetwarnings()
! Reset the warnings filter to empty.
! sys.setupwarnings(args)
! Parse command line options and initialize the warnings filter
! accordingly. The argument should be sys.argv[1:] or equivalent.
! Unrecognized options raise getopt.error. The return value is a
! list containing the remaining (non-option) arguments.
! Command Line Syntax
!
! There should be command line options to specify the most common
! filtering actions, which I expect to include at least:
!
! - suppress all warnings
!
! - suppress a particular warning message everywhere
!
! - suppress all warnings in a particular module
!
! - turn all warnings into exceptions
!
! I propose the following command line option syntax:
!
! -Waction[:message[:category[:module[:lineno]]]]
!
! Where:
!
! - 'action' is an abbreviation of one of the allowed actions
! ("error", "default", "ignore", "always", "once", or "module")
!
! - 'message' is a message string; matches warnings whose message
! text is an initial substring of 'message' (matching is
! case-sensitive)
!
! - 'category' is an abbreviation of a standard warning category
! class name *or* a fully-qualified name for a user-defined
! warning category class of the form [package.]module.classname
!
! - 'module' is a module name (possibly package.module)
!
! - 'lineno' is an integral line number
!
! All parts except 'action' may be omitted, where an empty value
! after stripping whitespace is the same as an omitted value.
!
! Each -W option results into a call to sys.filterwarnings(); thus
! later -W options override earlier -W options for warnings they
! both match.
!
! Examples:
!
! -Werror
! Turn all warnings into errors
!
! -Wall
! Show all warnings
!
! -Wignore
! Ignore all warnings
! -Wi:hello
! Ignore warnings whose message text starts with "hello"
! -We::Deprecation
! Turn deprecation warnings into errors
! -Wi:::spam:10
! Ignore all warnings on line 10 of module spam
! -Wi:::spam -Wd:::spam:10
! Ignore all warnings in module spam except on line 10
!
! -We::Deprecation -Wd::Deprecation:spam
! Turn deprecation warnings into errors except in module spam
!
!
! Open Issues
!
! Some open issues off the top of my head:
!
! - The proposal has all the Python API functions in the sys module,
! except that the warning categories are in the warnings module.
! Perhaps everything should be in the warnings module (like the
! prototype implementation)? Or perhaps warn() should be promoted
! to a built-in (i.e. in the __builtin__ module)?
!
! - It's tempting to leave the implementation in Python and add an
! absolute minimal amount of C code, only to make the standard
! warning categories available from C code. The Py_Warn()
! function could call warnings.warn(). Similarly, the Python
! main() function could collect -W options and pass them to
! warnings.setupwarnings().
!
! - The prototype implements a third argument to warn():
!
! warn(message, category=UserWarning, level=1)
!
! The 'level' argument could be used by wrapper functions written
! in Python, like this:
!
! def deprecation(message):
! warn(message, DeprecationWarning, level=2)
!
! This makes the warning refer to the deprecation()'s caller,
! rather than to the source of deprecation() itself (the latter
! would defeat the purpose of the warning message).
!
! - The proposed command line syntax is ugly (although the simple
! cases aren't so bad: -Werror, -Wignore, etc.). Anybody got a
! better idea?
!
! - I'm a bit worried that the filter specifications are too
! complex. Perhaps filtering only on category and module (not on
! message text and line number) would be enough?
!
! - There's a bit of confusion between module names and file names.
! The reporting uses file names, but the filter specification uses
! module names. Maybe it should allow filenames as well?
!
! - I'm not at all convinced that packages are handled right.
!
! - Better names for the various API functions?
!
!
! Implementation
! Here's a prototype implementation:
+ http://sourceforge.net/patch/?func=detailpatch&patch_id=102715&group_id=5470