[Python-checkins] CVS: python/nondist/peps pep-0230.txt,1.3,1.4

Guido van Rossum python-dev@python.org
Mon, 11 Dec 2000 08:34:37 -0800


Update of /cvsroot/python/python/nondist/peps
In directory slayer.i.sourceforge.net:/tmp/cvs-serv16049

Modified Files:
	pep-0230.txt 
Log Message:
New version of the PEP.  Changes based upon the second
(delayed-import) implentation.  Address some of Paul's concerns.


Index: pep-0230.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0230.txt,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** pep-0230.txt	2000/12/07 21:52:14	1.3
--- pep-0230.txt	2000/12/11 16:34:34	1.4
***************
*** 17,21 ****
      on 05-Nov-2000, with some ideas (such as using classes to
      categorize warnings) merged in from Paul Prescod's
!     counter-proposal posted on the same date.
  
  
--- 17,22 ----
      on 05-Nov-2000, with some ideas (such as using classes to
      categorize warnings) merged in from Paul Prescod's
!     counter-proposal posted on the same date.  Also, an attempt to
!     implement the proposal caused several small tweaks.
  
  
***************
*** 75,112 ****
      - To issue a warning from Python:
  
!       sys.warn(message[, category])
  
        The category argument, if given, must be a warning category
        class (see below); it defaults to warnings.UserWarning.  This
        may raise an exception if the particular warning issued is
!       changed into an error by the warnings filter.
  
      - To issue a warning from C:
  
!       int Py_Warn(char *message, PyObject *category)
  
!       Return 0 normally, 1 if an exception is raised.  The category
!       argument must be a warning category class (see below).  When
!       Py_Warn() function returns 1, the caller should do normal
!       exception handling.  [Question: what about issuing warnings
!       during lexing or parsing, which don't have the exception
!       machinery available?]
  
  
  Warnings Categories
  
!     The "warnings" module defines classes representing warning
      categories.  This categorization is useful to be able to filter
!     out groups of warnings.  The classes defined in this module have
!     no semantics attached to them and are never instantiated -- only
!     their names are used for filtering (see the section on the
!     warnings filter below).  The following warnings category classes
      are currently defined:
  
      - Warning -- this is the base class of all warning category
!       classes.  A warning category must always be a subclass of this
!       class.
  
!     - UserWarning -- the default category for sys.warn()
  
      - DeprecationWarning -- base category for warnings about deprecated
--- 76,127 ----
      - To issue a warning from Python:
  
!         import warnings
!         warnings.warn(message[, category[, stacklevel]])
  
        The category argument, if given, must be a warning category
        class (see below); it defaults to warnings.UserWarning.  This
        may raise an exception if the particular warning issued is
!       changed into an error by the warnings filter.  The stacklevel
!       can 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 (since the
+       latter would defeat the purpose of the warning message).
+ 
      - To issue a warning from C:
+ 
+         int PyErr_Warn(PyObject *category, char *message);
  
!       Return 0 normally, 1 if an exception is raised (either because
!       the warning was transformed into an exception, or because of a
!       malfunction in the implementation, such as running out of
!       memory).  The category argument must be a warning category class
!       (see below) or NULL, in which case it defaults to
!       PyExc_RuntimeWarning.  When PyErr_Warn() function returns 1, the
!       caller should do normal exception handling.
! 
!       The current C implementation of PyErr_Warn() imports the
!       warnings module (implemented in Python) and calls its warn()
!       function.  This minimizes the amount of C code that needs to be
!       added to implement the warning feature.
  
!       [XXX Open Issue: what about issuing warnings during lexing or
!       parsing, which don't have the exception machinery available?]
  
  
  Warnings Categories
  
!     There are a number of built-in exceptions that represent warning
      categories.  This categorization is useful to be able to filter
!     out groups of warnings.  The following warnings category classes
      are currently defined:
  
      - Warning -- this is the base class of all warning category
!       classes and it itself a subclass of Exception
  
!     - UserWarning -- the default category for warnings.warn()
  
      - DeprecationWarning -- base category for warnings about deprecated
***************
*** 115,121 ****
      - SyntaxWarning -- base category for warnings about dubious
        syntactic features
  
!     Other categories may be proposed during the review period for this
!     PEP.
  
  
--- 130,147 ----
      - SyntaxWarning -- base category for warnings about dubious
        syntactic features
+ 
+     - RuntimeWarning -- base category for warnings about dubious
+       runtime features
+ 
+     [XXX: Other warning categories may be proposed during the review
+     period for this PEP.]
  
!     These standard warning categories are available from C as
!     PyExc_Warning, PyExc_UserWarning, etc.  From Python, they are
!     available in the __builtin__ module, so no import is necessary.
! 
!     User code can define additional warning categories by subclassing
!     one of the standard warning categories.  A warning category must
!     always be a subclass of the Warning class.
  
  
***************
*** 128,132 ****
  
      - The data structures used to efficiently determine the
!       disposition of a particular Py_Warn() call.
  
      - The API to control the filter from Python source code.
--- 154,159 ----
  
      - The data structures used to efficiently determine the
!       disposition of a particular warnings.warn() or PyErr_Warn()
!       call.
  
      - The API to control the filter from Python source code.
***************
*** 140,144 ****
      First, the warning filter collects the module and line number
      where the warning is issued; this information is readily available
!     through PyEval_GetFrame().
  
      Conceptually, the warnings filter maintains an ordered list of
--- 167,171 ----
      First, the warning filter collects the module and line number
      where the warning is issued; this information is readily available
!     through sys._getframe().
  
      Conceptually, the warnings filter maintains an ordered list of
***************
*** 153,160 ****
        the warning category must be a subclass in order to match
  
!     - message is a regular expression that the warning message must
!       match
  
!     - module is a regular expression that the module name must match
  
      - lineno is an integer that the line number where the warning
--- 180,188 ----
        the warning category must be a subclass in order to match
  
!     - message is a compiled regular expression that the warning
!       message must match
  
!     - module is a compiled regular expression that the module name
!       must match
  
      - lineno is an integer that the line number where the warning
***************
*** 178,213 ****
            warnings
  
!     The Warning class is derived from the built-in Exception class, so
!     that to turn a warning into an error we raise category(message).
  
  
! The Warnings Output Hook
  
      When the warnings filter decides to issue a warning (but not when
      it decides to raise an exception), it passes the information about
!     the function sys.showwarning(message, category, filename, lineno).
      The default implementation of this function writes the warning text
!     to sys.stderr, and shows the source line of the filename.
  
  
  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
  
--- 206,244 ----
            warnings
  
!     Since the Warning class is derived from the built-in Exception
!     class, to turn a warning into an error we simply raise
!     category(message).
  
  
! Warnings Output And Formatting Hooks
  
      When the warnings filter decides to issue a warning (but not when
      it decides to raise an exception), it passes the information about
!     the function warnings.showwarning(message, category, filename, lineno).
      The default implementation of this function writes the warning text
!     to sys.stderr, and shows the source line of the filename.  It has
!     an optional 5th argument which can be used to specify a different
!     file than sys.stderr.
! 
!     The formatting of warnings is done by a separate function,
!     warnings.formatwarning(message, category, filename, lineno).  This
!     returns a string (that may contain newlines and ends in a newline)
!     that can be printed to get the identical effect of the
!     showwarning() function.
  
  
  API For Manipulating Warning Filters
  
!       warnings.filterwarnings(message, category, module, lineno, action)
  
!     This checks the types of the arguments, compiles the message and
!     module regular expressions, and inserts them as a tuple in front
!     of the warnings filter.
  
!       warnings.resetwarnings()
  
      Reset the warnings filter to empty.
  
  
  Command Line Syntax
  
***************
*** 247,253 ****
      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:
--- 278,287 ----
      after stripping whitespace is the same as an omitted value.
  
!     The C code that parses the Python command line saves the body of
!     all -W options in a list of strings, which is made available to
!     the warnings module as sys.warnoptions.  The warnings module
!     parses these when it is first imported.  Errors detected during
!     the parsing of sys.warnoptions are not fatal; a message is written
!     to sys.stderr and processing continues with the option.
  
      Examples:
***************
*** 281,315 ****
  
      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
--- 315,325 ----
  
      Some open issues off the top of my head:
  
!     - What about issuing warnings during lexing or parsing, which
!       don't have the exception machinery available?
  
!     - The proposed command line syntax is a bit 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
***************
*** 322,327 ****
  
      - I'm not at all convinced that packages are handled right.
  
!     - Better names for the various API functions?
  
  
--- 332,372 ----
  
      - I'm not at all convinced that packages are handled right.
+ 
+     - Do we need more standard warning categories?  Fewer?
+ 
+     - In order to minimize the start-up overhead, the warnings module
+       is imported by the first call to PyErr_Warn().  It does the
+       command line parsing for -W options upon import.  Therefore, it
+       is possible that warning-free programs will not complain about
+       invalid -W options.
+ 
+ 
+ Rejected Concerns
+ 
+     Paul Prescod has brought up several additional concerns that I
+     feel aren't critical.  I address them here (the concerns are
+     paraphrased, not necessarily exactly Paul's words).
+ 
+     - Paul: warn() should be a built-in or a statement to make it easily
+       available.
+ 
+       Response: "from warnings import warn" is easy enough.
+ 
+     - Paul: What if I have a speed-critical module that triggers
+       warnings in an inner loop.  It should be possible to disable the
+       overhead for detecting the warning (not just suppress the
+       warning).
+ 
+       Response: rewrite the inner loop to avoid triggering the
+       warning.
+ 
+     - Paul: What if I want to see the full context of a warning?
+ 
+       Response: use -Werror to turn it into an exception.
+ 
+     - Paul: I prefer ":*:*:" to ":::" for leaving parts of the warning
+       spec out.
  
!       Response: I don't.