On Monday 08 January 2007 16:50, Anthony Baxter wrote:
> I've been thinking a little about how and where we'd add warnings
> to 2.6 and later for things that will break in 3.0. My first idea
> is to add a command line option '-3' (or maybe '-warn3')
> implemented as "from __future__ import py3k". We can then put
> code in that optionally generates a warning if this is set.

Ok, I lied - I implemented this pretty easily just now (patch 
attached). As a first pass, I put in warnings for dict.has_key and 
the builtin apply() function. 

I've changed my mind about the from future statement. I think that
'from __future__ import py3k' says "please use whatever backwards 
incompatible 3.x features that you support". I guess we could have 
something like 'from __future__ import warn3k', perhaps. But this 
wouldn't take effect for just the current source file, so could be 
confusing. 

If people are happy with this, I'll check it into the trunk, then 
people can go crazy adding other warnings for 3.0-isms. 

beaker% ./python
Python 2.6a0 (trunk:53285:53286M, Jan  8 2007, 18:34:47) 
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more 
information.
>>> 1 in {}
False
>>> {}.has_key(1)
False
>>> apply(lambda x:None, (1,))
>>> 
beaker% ./python -3 
Python 2.6a0 (trunk:53285:53286M, Jan  8 2007, 18:34:47) 
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more 
information.
>>> 1 in {}
False
>>> {}.has_key(1)
__main__:1: DeprecationWarning: dict.has_key not supported in 3.x
False
>>> apply(lambda x:None, (1,))
__main__:1: DeprecationWarning: apply() not supported in 3.x
>>> 

Anthony
Index: Python/bltinmodule.c
===================================================================
--- Python/bltinmodule.c	(revision 53285)
+++ Python/bltinmodule.c	(working copy)
@@ -144,6 +144,12 @@
 	PyObject *func, *alist = NULL, *kwdict = NULL;
 	PyObject *t = NULL, *retval = NULL;
 
+        if (Py_Py3kWarningFlag &&
+                PyErr_Warn(PyExc_DeprecationWarning, 
+                    "apply() not supported in 3.x") < 0) {
+            return NULL;
+        }
+
 	if (!PyArg_UnpackTuple(args, "apply", 1, 3, &func, &alist, &kwdict))
 		return NULL;
 	if (alist != NULL) {
Index: Include/pydebug.h
===================================================================
--- Include/pydebug.h	(revision 53285)
+++ Include/pydebug.h	(working copy)
@@ -20,6 +20,8 @@
   on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
   true divisions (which they will be in 3.0). */
 PyAPI_DATA(int) _Py_QnewFlag;
+/* Warn about 3.x issues */
+PyAPI_DATA(int) Py_Py3kWarningFlag;
 
 /* this is a wrapper around getenv() that pays attention to
    Py_IgnoreEnvironmentFlag.  It should be used for getting variables like
Index: Objects/object.c
===================================================================
--- Objects/object.c	(revision 53285)
+++ Objects/object.c	(working copy)
@@ -29,6 +29,7 @@
 #endif /* Py_REF_DEBUG */
 
 int Py_DivisionWarningFlag;
+int Py_Py3kWarningFlag;
 
 /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
    These are used by the individual routines for object creation.
Index: Objects/dictobject.c
===================================================================
--- Objects/dictobject.c	(revision 53285)
+++ Objects/dictobject.c	(working copy)
@@ -1647,6 +1647,11 @@
 	long hash;
 	dictentry *ep;
 
+        if (Py_Py3kWarningFlag &&
+                PyErr_Warn(PyExc_DeprecationWarning, 
+                    "dict.has_key not supported in 3.x") < 0) {
+            return NULL;
+        }
 	if (!PyString_CheckExact(key) ||
 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
 		hash = PyObject_Hash(key);
@@ -1660,6 +1665,24 @@
 }
 
 static PyObject *
+dict_contains(register dictobject *mp, PyObject *key)
+{
+	long hash;
+	dictentry *ep;
+
+	if (!PyString_CheckExact(key) ||
+	    (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+		hash = PyObject_Hash(key);
+		if (hash == -1)
+			return NULL;
+	}
+	ep = (mp->ma_lookup)(mp, key, hash);
+	if (ep == NULL)
+		return NULL;
+	return PyBool_FromLong(ep->me_value != NULL);
+}
+
+static PyObject *
 dict_get(register dictobject *mp, PyObject *args)
 {
 	PyObject *key;
@@ -1932,7 +1955,7 @@
 "D.iteritems() -> an iterator over the (key, value) items of D");
 
 static PyMethodDef mapp_methods[] = {
-	{"__contains__",(PyCFunction)dict_has_key,      METH_O | METH_COEXIST,
+	{"__contains__",(PyCFunction)dict_contains,      METH_O | METH_COEXIST,
 	 contains__doc__},
 	{"__getitem__", (PyCFunction)dict_subscript,	METH_O | METH_COEXIST,
 	 getitem__doc__},
Index: Modules/main.c
===================================================================
--- Modules/main.c	(revision 53285)
+++ Modules/main.c	(working copy)
@@ -40,7 +40,7 @@
 static int  orig_argc;
 
 /* command line options */
-#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX?"
+#define BASE_OPTS "3c:dEhim:OQ:StuUvVW:xX?"
 
 #ifndef RISCOS
 #define PROGRAM_OPTS BASE_OPTS
@@ -82,6 +82,7 @@
 -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\
+-3     : warn about Python 3.x incompatibilities\n\
 file   : program read from script file\n\
 -      : program read from stdin (default; interactive mode if a tty)\n\
 ";
@@ -269,6 +270,10 @@
 			Py_DebugFlag++;
 			break;
 
+                case '3':
+                        Py_Py3kWarningFlag++;
+                        break;
+
 		case 'Q':
 			if (strcmp(_PyOS_optarg, "old") == 0) {
 				Py_DivisionWarningFlag = 0;
_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: 
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com

Reply via email to