[Python-3000-checkins] r58876 - in python/branches/py3k-pep3137: Doc/library/exceptions.rst Doc/library/warnings.rst Include/pydebug.h Include/pyerrors.h Lib/test/exception_hierarchy.txt Lib/test/test_bytes.py Lib/test/test_unicode.py Misc/NEWS Modules/main.c Objects/bytesobject.c Objects/exceptions.c Objects/stringobject.c Python/pythonrun.c
christian.heimes
python-3000-checkins at python.org
Tue Nov 6 12:52:33 CET 2007
Author: christian.heimes
Date: Tue Nov 6 12:52:32 2007
New Revision: 58876
Modified:
python/branches/py3k-pep3137/Doc/library/exceptions.rst
python/branches/py3k-pep3137/Doc/library/warnings.rst
python/branches/py3k-pep3137/Include/pydebug.h
python/branches/py3k-pep3137/Include/pyerrors.h
python/branches/py3k-pep3137/Lib/test/exception_hierarchy.txt
python/branches/py3k-pep3137/Lib/test/test_bytes.py
python/branches/py3k-pep3137/Lib/test/test_unicode.py
python/branches/py3k-pep3137/Misc/NEWS
python/branches/py3k-pep3137/Modules/main.c
python/branches/py3k-pep3137/Objects/bytesobject.c
python/branches/py3k-pep3137/Objects/exceptions.c
python/branches/py3k-pep3137/Objects/stringobject.c
python/branches/py3k-pep3137/Python/pythonrun.c
Log:
Applied my patch #1392 to issue warnings or errors for certain operations that involve str and byte/buffer operations like str(bytes()) or str() == bytes(). The code paths are only enabled with the new argument -b.
* Added class BytesWarning(Warning)
* Added -b/-bb command line args and Py_BytesWarningFlag
* issue PyErr_WarnEx(PyExc_BytesWarning) when Py_BytesWarningFlag is set.
* Added warning filter for BytesWarning that raises an exception if
Py_BytesWarningFlag > 1
Please run the regression tests with -bb to catch problems. I've added filters around some test cases to ignore the operations when it's appropriate.
Modified: python/branches/py3k-pep3137/Doc/library/exceptions.rst
==============================================================================
--- python/branches/py3k-pep3137/Doc/library/exceptions.rst (original)
+++ python/branches/py3k-pep3137/Doc/library/exceptions.rst Tue Nov 6 12:52:32 2007
@@ -405,6 +405,10 @@
Base class for warnings related to Unicode.
+.. exception:: BytesWarning
+
+ Base class for warnings related to bytes and buffer.
+
The class hierarchy for built-in exceptions is:
Modified: python/branches/py3k-pep3137/Doc/library/warnings.rst
==============================================================================
--- python/branches/py3k-pep3137/Doc/library/warnings.rst (original)
+++ python/branches/py3k-pep3137/Doc/library/warnings.rst Tue Nov 6 12:52:32 2007
@@ -80,6 +80,10 @@
| :exc:`UnicodeWarning` | Base category for warnings related to |
| | Unicode. |
+----------------------------------+-----------------------------------------------+
+| :exc:`BytesWarning` | Base category for warnings related to |
+| | bytes and buffer. |
++----------------------------------+-----------------------------------------------+
+
While these are technically built-in exceptions, they are documented here,
because conceptually they belong to the warnings mechanism.
Modified: python/branches/py3k-pep3137/Include/pydebug.h
==============================================================================
--- python/branches/py3k-pep3137/Include/pydebug.h (original)
+++ python/branches/py3k-pep3137/Include/pydebug.h Tue Nov 6 12:52:32 2007
@@ -11,6 +11,7 @@
PyAPI_DATA(int) Py_InspectFlag;
PyAPI_DATA(int) Py_OptimizeFlag;
PyAPI_DATA(int) Py_NoSiteFlag;
+PyAPI_DATA(int) Py_BytesWarningFlag;
PyAPI_DATA(int) Py_UseClassExceptionsFlag;
PyAPI_DATA(int) Py_FrozenFlag;
PyAPI_DATA(int) Py_TabcheckFlag;
Modified: python/branches/py3k-pep3137/Include/pyerrors.h
==============================================================================
--- python/branches/py3k-pep3137/Include/pyerrors.h (original)
+++ python/branches/py3k-pep3137/Include/pyerrors.h Tue Nov 6 12:52:32 2007
@@ -165,6 +165,7 @@
PyAPI_DATA(PyObject *) PyExc_FutureWarning;
PyAPI_DATA(PyObject *) PyExc_ImportWarning;
PyAPI_DATA(PyObject *) PyExc_UnicodeWarning;
+PyAPI_DATA(PyObject *) PyExc_BytesWarning;
/* Convenience functions */
Modified: python/branches/py3k-pep3137/Lib/test/exception_hierarchy.txt
==============================================================================
--- python/branches/py3k-pep3137/Lib/test/exception_hierarchy.txt (original)
+++ python/branches/py3k-pep3137/Lib/test/exception_hierarchy.txt Tue Nov 6 12:52:32 2007
@@ -44,5 +44,6 @@
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
- +-- ImportWarning
- +-- UnicodeWarning
+ +-- ImportWarning
+ +-- UnicodeWarning
+ +-- BytesWarning
Modified: python/branches/py3k-pep3137/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k-pep3137/Lib/test/test_bytes.py (original)
+++ python/branches/py3k-pep3137/Lib/test/test_bytes.py Tue Nov 6 12:52:32 2007
@@ -12,6 +12,7 @@
import pickle
import tempfile
import unittest
+import warnings
import test.test_support
import test.string_tests
import test.buffer_tests
@@ -19,6 +20,12 @@
class BytesTest(unittest.TestCase):
+ def setUp(self):
+ self.warning_filters = warnings.filters[:]
+
+ def tearDown(self):
+ warnings.filters = self.warning_filters
+
def test_basics(self):
b = buffer()
self.assertEqual(type(b), buffer)
@@ -87,6 +94,7 @@
self.assertRaises(ValueError, buffer, [10**100])
def test_repr_str(self):
+ warnings.simplefilter('ignore', BytesWarning)
for f in str, repr:
self.assertEqual(f(buffer()), "buffer(b'')")
self.assertEqual(f(buffer([0])), "buffer(b'\\x00')")
@@ -149,6 +157,8 @@
self.assertEqual(bytes(b"abc") < b"ab", False)
self.assertEqual(bytes(b"abc") <= b"ab", False)
+ def test_compare_to_str(self):
+ warnings.simplefilter('ignore', BytesWarning)
# Byte comparisons with unicode should always fail!
# Test this for all expected byte orders and Unicode character sizes
self.assertEqual(b"\0a\0b\0c" == "abc", False)
@@ -371,6 +381,7 @@
self.assertEqual(b, buffer(sample))
def test_to_str(self):
+ warnings.simplefilter('ignore', BytesWarning)
self.assertEqual(str(b''), "b''")
self.assertEqual(str(b'x'), "b'x'")
self.assertEqual(str(b'\x80'), "b'\\x80'")
Modified: python/branches/py3k-pep3137/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k-pep3137/Lib/test/test_unicode.py (original)
+++ python/branches/py3k-pep3137/Lib/test/test_unicode.py Tue Nov 6 12:52:32 2007
@@ -6,7 +6,11 @@
(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
"""#"
-import unittest, sys, struct, codecs, new
+import codecs
+import struct
+import sys
+import unittest
+import warnings
from test import test_support, string_tests
# Error handling (bad decoder return)
@@ -34,6 +38,12 @@
):
type2test = str
+ def setUp(self):
+ self.warning_filters = warnings.filters[:]
+
+ def tearDown(self):
+ warnings.filters = self.warning_filters
+
def checkequalnofix(self, result, object, methodname, *args):
method = getattr(object, methodname)
realresult = method(*args)
@@ -205,6 +215,7 @@
self.assertRaises(TypeError, 'replace'.replace, "r", 42)
def test_bytes_comparison(self):
+ warnings.simplefilter('ignore', BytesWarning)
self.assertEqual('abc' == b'abc', False)
self.assertEqual('abc' != b'abc', True)
self.assertEqual('abc' == buffer(b'abc'), False)
Modified: python/branches/py3k-pep3137/Misc/NEWS
==============================================================================
--- python/branches/py3k-pep3137/Misc/NEWS (original)
+++ python/branches/py3k-pep3137/Misc/NEWS Tue Nov 6 12:52:32 2007
@@ -31,6 +31,9 @@
- io.open() and _fileio.FileIO have grown a new argument closefd. A false
value disables the closing of the file descriptor.
+- Added a new option -b to issues warnings (-bb for errors) about certain
+ operations between bytes/buffer and str like str(b'') and comparsion.
+
Extension Modules
-----------------
Modified: python/branches/py3k-pep3137/Modules/main.c
==============================================================================
--- python/branches/py3k-pep3137/Modules/main.c (original)
+++ python/branches/py3k-pep3137/Modules/main.c Tue Nov 6 12:52:32 2007
@@ -44,7 +44,7 @@
static int orig_argc;
/* command line options */
-#define BASE_OPTS "c:dEhim:OStuvVW:xX?"
+#define BASE_OPTS "bc:dEhim:OStuvVW:xX?"
#define PROGRAM_OPTS BASE_OPTS
@@ -55,32 +55,34 @@
/* Long usage message, split into parts < 512 bytes */
static char *usage_1 = "\
Options and arguments (and corresponding environment variables):\n\
+-b : issue warnings about str(bytes_instance), str(buffer_instance)\n\
+ and comparing bytes/buffer with str. (-bb: issue errors)\n\
-c cmd : program passed in as string (terminates option list)\n\
-d : debug output from parser; also PYTHONDEBUG=x\n\
-E : ignore environment variables (such as PYTHONPATH)\n\
-h : print this help message and exit (also --help)\n\
--i : inspect interactively after running script; forces a prompt even\n\
- if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
";
static char *usage_2 = "\
+-i : inspect interactively after running script; forces a prompt even\n\
+ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
-m mod : run library module as a script (terminates option list)\n\
-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
-OO : remove doc-strings in addition to the -O optimizations\n\
-S : don't imply 'import site' on initialization\n\
-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
--u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
";
static char *usage_3 = "\
+-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
see man page for details on internal buffering relating to '-u'\n\
-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
can be supplied multiple times to increase verbosity\n\
-V : print the Python version number and exit (also --version)\n\
-W arg : warning control; arg is action:message:category:module:lineno\n\
-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
-file : program read from script file\n\
-- : program read from stdin (default; interactive mode if a tty)\n\
";
static char *usage_4 = "\
+file : program read from script file\n\
+- : program read from stdin (default; interactive mode if a tty)\n\
arg ...: arguments passed to program in sys.argv[1:]\n\n\
Other environment variables:\n\
PYTHONSTARTUP: file executed on interactive startup (no default)\n\
@@ -252,6 +254,9 @@
}
switch (c) {
+ case 'b':
+ Py_BytesWarningFlag++;
+ break;
case 'd':
Py_DebugFlag++;
Modified: python/branches/py3k-pep3137/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k-pep3137/Objects/bytesobject.c (original)
+++ python/branches/py3k-pep3137/Objects/bytesobject.c Tue Nov 6 12:52:32 2007
@@ -917,6 +917,17 @@
}
static PyObject *
+bytes_str(PyObject *op)
+{
+ if (Py_BytesWarningFlag) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "str() on a buffer instance", 1))
+ return NULL;
+ }
+ return bytes_repr((PyBytesObject*)op);
+}
+
+static PyObject *
bytes_richcompare(PyObject *self, PyObject *other, int op)
{
Py_ssize_t self_size, other_size;
@@ -930,6 +941,12 @@
error, even if the comparison is for equality. */
if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
+ if (Py_BytesWarningFlag && op == Py_EQ) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "Comparsion between buffer and string", 1))
+ return NULL;
+ }
+
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
@@ -3082,7 +3099,7 @@
&bytes_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
- (reprfunc)bytes_repr, /* tp_str */
+ bytes_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&bytes_as_buffer, /* tp_as_buffer */
Modified: python/branches/py3k-pep3137/Objects/exceptions.c
==============================================================================
--- python/branches/py3k-pep3137/Objects/exceptions.c (original)
+++ python/branches/py3k-pep3137/Objects/exceptions.c Tue Nov 6 12:52:32 2007
@@ -1740,6 +1740,14 @@
"Base class for warnings about Unicode related problems, mostly\n"
"related to conversion problems.");
+/*
+ * BytesWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, BytesWarning,
+ "Base class for warnings about bytes and buffer related problems, mostly\n"
+ "related to conversion from str or comparing to str.");
+
+
/* Pre-computed MemoryError instance. Best to create this as early as
* possible and not wait until a MemoryError is actually raised!
@@ -1839,6 +1847,7 @@
PRE_INIT(FutureWarning)
PRE_INIT(ImportWarning)
PRE_INIT(UnicodeWarning)
+ PRE_INIT(BytesWarning)
bltinmod = PyImport_ImportModule("__builtin__");
if (bltinmod == NULL)
@@ -1899,6 +1908,7 @@
POST_INIT(FutureWarning)
POST_INIT(ImportWarning)
POST_INIT(UnicodeWarning)
+ POST_INIT(BytesWarning)
PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
if (!PyExc_MemoryErrorInst)
Modified: python/branches/py3k-pep3137/Objects/stringobject.c
==============================================================================
--- python/branches/py3k-pep3137/Objects/stringobject.c (original)
+++ python/branches/py3k-pep3137/Objects/stringobject.c Tue Nov 6 12:52:32 2007
@@ -679,6 +679,17 @@
return PyString_Repr(op, 1);
}
+static PyObject *
+string_str(PyObject *op)
+{
+ if (Py_BytesWarningFlag) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "str() on a bytes instance", 1))
+ return NULL;
+ }
+ return string_repr(op);
+}
+
static Py_ssize_t
string_length(PyStringObject *a)
{
@@ -830,6 +841,15 @@
/* Make sure both arguments are strings. */
if (!(PyString_Check(a) && PyString_Check(b))) {
+ if (Py_BytesWarningFlag && (op == Py_EQ) &&
+ (PyObject_IsInstance((PyObject*)a,
+ (PyObject*)&PyUnicode_Type) ||
+ PyObject_IsInstance((PyObject*)b,
+ (PyObject*)&PyUnicode_Type))) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "Comparsion between bytes and string", 1))
+ return NULL;
+ }
result = Py_NotImplemented;
goto out;
}
@@ -3074,13 +3094,13 @@
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- string_repr, /* tp_repr */
+ (reprfunc)string_repr, /* tp_repr */
0, /* tp_as_number */
&string_as_sequence, /* tp_as_sequence */
&string_as_mapping, /* tp_as_mapping */
(hashfunc)string_hash, /* tp_hash */
0, /* tp_call */
- string_repr, /* tp_str */
+ string_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&string_as_buffer, /* tp_as_buffer */
Modified: python/branches/py3k-pep3137/Python/pythonrun.c
==============================================================================
--- python/branches/py3k-pep3137/Python/pythonrun.c (original)
+++ python/branches/py3k-pep3137/Python/pythonrun.c Tue Nov 6 12:52:32 2007
@@ -75,6 +75,7 @@
int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */
int Py_NoSiteFlag; /* Suppress 'import site' */
+int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
int Py_FrozenFlag; /* Needed by getpath.c */
int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
@@ -262,8 +263,28 @@
#endif /* WITH_THREAD */
warnings_module = PyImport_ImportModule("warnings");
- if (!warnings_module)
+ if (!warnings_module) {
PyErr_Clear();
+ }
+ else {
+ PyObject *o;
+ char *action[8];
+
+ if (Py_BytesWarningFlag > 1)
+ *action = "error";
+ else if (Py_BytesWarningFlag)
+ *action = "default";
+ else
+ *action = "ignore";
+
+ o = PyObject_CallMethod(warnings_module,
+ "simplefilter", "sO",
+ *action, PyExc_BytesWarning);
+ if (o == NULL)
+ Py_FatalError("Py_Initialize: can't initialize"
+ "warning filter for BytesWarning.");
+ Py_DECREF(o);
+ }
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
/* On Unix, set the file system encoding according to the
More information about the Python-3000-checkins
mailing list