[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