Python-checkins
Threads by month
- ----- 2025 -----
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
February 2007
- 15 participants
- 441 discussions

r54014 - sandbox/trunk/2to3/tests/support.py sandbox/trunk/2to3/tests/test_fixers.py
by collin.winter Feb. 27, 2007
by collin.winter Feb. 27, 2007
Feb. 27, 2007
Author: collin.winter
Date: Wed Feb 28 02:33:51 2007
New Revision: 54014
Modified:
sandbox/trunk/2to3/tests/support.py
sandbox/trunk/2to3/tests/test_fixers.py
Log:
Move reformat() into tests.support
Modified: sandbox/trunk/2to3/tests/support.py
==============================================================================
--- sandbox/trunk/2to3/tests/support.py (original)
+++ sandbox/trunk/2to3/tests/support.py Wed Feb 28 02:33:51 2007
@@ -4,14 +4,26 @@
import unittest
import sys
import os.path
+import re
+
+TestCase = unittest.TestCase
def run_all_tests(test_mod=None, tests=None):
if tests is None:
tests = unittest.TestLoader().loadTestsFromModule(test_mod)
unittest.TextTestRunner(verbosity=2).run(tests)
+
def adjust_path():
parent_dir = os.path.split(sys.path[0])[0]
sys.path = [parent_dir] + sys.path
-TestCase = unittest.TestCase
+
+skip_whitespace = re.compile(r"""\S""")
+def reformat(string):
+ indent = re.search(skip_whitespace, string).start()
+ if indent == 0:
+ code = string
+ else:
+ code = "\n".join(line[indent-1:] for line in string.split("\n")[1:])
+ return code + "\n\n"
Modified: sandbox/trunk/2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_fixers.py (original)
+++ sandbox/trunk/2to3/tests/test_fixers.py Wed Feb 28 02:33:51 2007
@@ -9,7 +9,6 @@
# Python imports
from StringIO import StringIO
-import re
import unittest
import logging
@@ -17,16 +16,6 @@
import pytree
import refactor
-skip_whitespace = re.compile(r"""\S""")
-
-def reformat(string):
- indent = re.search(skip_whitespace, string).start()
- if indent == 0:
- code = string
- else:
- code = "\n".join(line[indent-1:] for line in string.split("\n")[1:])
- return code + "\n\n"
-
# We wrap the RefactoringTool's fixer objects so we can intercept
# the call to set_filename() and so modify the fixers' logging objects.
# This allows us to make sure that certain code chunks produce certain
@@ -61,8 +50,8 @@
self.refactor.fixers = [Fixer(f, sh) for f in self.refactor.fixers]
def check(self, before, after):
- before = reformat(before)
- after = reformat(after)
+ before = support.reformat(before)
+ after = support.reformat(after)
refactored = self.refactor_stream("<string>", StringIO(before))
self.failUnlessEqual(after, refactored)
1
0

r54013 - in python/branches/p3yk_no_args_on_exc: Include/pyerrors.h Lib/test/test_exception_variations.py Lib/test/test_exceptions.py Lib/test/test_pep352.py Misc/NEWS Objects/exceptions.c
by brett.cannon Feb. 27, 2007
by brett.cannon Feb. 27, 2007
Feb. 27, 2007
Author: brett.cannon
Date: Wed Feb 28 02:04:17 2007
New Revision: 54013
Modified:
python/branches/p3yk_no_args_on_exc/Include/pyerrors.h
python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py
python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py
python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py
python/branches/p3yk_no_args_on_exc/Misc/NEWS
python/branches/p3yk_no_args_on_exc/Objects/exceptions.c
Log:
Checkpoint of PyCon work done in local copy of p3yk.
Modified: python/branches/p3yk_no_args_on_exc/Include/pyerrors.h
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Include/pyerrors.h (original)
+++ python/branches/p3yk_no_args_on_exc/Include/pyerrors.h Wed Feb 28 02:04:17 2007
@@ -9,14 +9,12 @@
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
} PyBaseExceptionObject;
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
PyObject *msg;
PyObject *filename;
@@ -30,7 +28,6 @@
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
PyObject *encoding;
PyObject *object;
@@ -43,7 +40,6 @@
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
PyObject *code;
} PySystemExitObject;
@@ -51,7 +47,6 @@
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
PyObject *myerrno;
PyObject *strerror;
@@ -62,7 +57,6 @@
typedef struct {
PyObject_HEAD
PyObject *dict;
- PyObject *args;
PyObject *message;
PyObject *myerrno;
PyObject *strerror;
Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py (original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py Wed Feb 28 02:04:17 2007
@@ -1,4 +1,3 @@
-
from test.test_support import run_unittest
import unittest
Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py (original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py Wed Feb 28 02:04:17 2007
@@ -203,71 +203,51 @@
# test that exception attributes are happy
exceptionList = [
- (BaseException, (), {'message' : '', 'args' : ()}),
- (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
+ (BaseException, (), {'message' : ''}),
+ (BaseException, (1, ), {'message' : 1}),
(BaseException, ('foo',),
- {'message' : 'foo', 'args' : ('foo',)}),
- (BaseException, ('foo', 1),
- {'message' : '', 'args' : ('foo', 1)}),
+ {'message' : 'foo'}),
(SystemExit, ('foo',),
- {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
+ {'message' : 'foo', 'code' : 'foo'}),
(IOError, ('foo',),
- {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
- 'errno' : None, 'strerror' : None}),
+ {'message' : 'foo', 'filename' : None, 'errno' : 'foo',
+ 'strerror' : None}),
(IOError, ('foo', 'bar'),
- {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
- 'errno' : 'foo', 'strerror' : 'bar'}),
+ {'message' : 'foo', 'filename' : None, 'errno' : 'foo',
+ 'strerror' : 'bar'}),
(IOError, ('foo', 'bar', 'baz'),
- {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
- 'errno' : 'foo', 'strerror' : 'bar'}),
- (IOError, ('foo', 'bar', 'baz', 'quux'),
- {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
+ {'message' : 'foo', 'filename' : 'baz', 'errno' : 'foo',
+ 'strerror' : 'bar'}),
(EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
- {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
- 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
- 'filename' : 'filenameStr'}),
+ {'message' : 'errnoStr', 'strerror' : 'strErrorStr',
+ 'errno' : 'errnoStr', 'filename' : 'filenameStr'}),
(EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
- {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
- 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
+ {'message' : 1, 'errno' : 1, 'strerror' : 'strErrorStr',
+ 'filename' : 'filenameStr'}),
(SyntaxError, ('msgStr',),
- {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
- 'print_file_and_line' : None, 'msg' : 'msgStr',
+ {'message' : 'msgStr', 'text' : None,
+ 'print_file_and_line' : None, 'msg' : 'msgStr',
'filename' : None, 'lineno' : None, 'offset' : None}),
(SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
'textStr')),
- {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
- 'args' : ('msgStr', ('filenameStr', 'linenoStr',
- 'offsetStr', 'textStr')),
+ {'message' : 'msgStr', 'offset' : 'offsetStr', 'text' : 'textStr',
'print_file_and_line' : None, 'msg' : 'msgStr',
'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
- (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
- 'textStr', 'print_file_and_lineStr'),
- {'message' : '', 'text' : None,
- 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
- 'textStr', 'print_file_and_lineStr'),
- 'print_file_and_line' : None, 'msg' : 'msgStr',
- 'filename' : None, 'lineno' : None, 'offset' : None}),
- (UnicodeError, (), {'message' : '', 'args' : (),}),
+ (UnicodeError, (), {'message' : ''}),
(UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
- {'message' : '', 'args' : ('ascii', u'a', 0, 1,
- 'ordinal not in range'),
- 'encoding' : 'ascii', 'object' : u'a',
+ {'message' : 'ascii', 'encoding' : 'ascii', 'object' : u'a',
'start' : 0, 'reason' : 'ordinal not in range'}),
(UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
- {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
- 'ordinal not in range'),
- 'encoding' : 'ascii', 'object' : '\xff',
+ {'message' : 'ascii', 'encoding' : 'ascii', 'object' : '\xff',
'start' : 0, 'reason' : 'ordinal not in range'}),
(UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
- {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
- 'object' : u'\u3042', 'reason' : 'ouch',
+ {'message' : u"\u3042", 'object' : u'\u3042', 'reason' : 'ouch',
'start' : 0, 'end' : 1}),
]
try:
exceptionList.append(
(WindowsError, (1, 'strErrorStr', 'filenameStr'),
- {'message' : '', 'args' : (1, 'strErrorStr'),
- 'strerror' : 'strErrorStr', 'winerror' : 1,
+ {'message' : 1, 'strerror' : 'strErrorStr', 'winerror' : 1,
'errno' : 22, 'filename' : 'filenameStr'})
)
except NameError:
@@ -279,15 +259,17 @@
except BaseException as e:
if type(e) is not exc:
raise
+ print(repr(e), ':', args)
# Verify module name
self.assertEquals(type(e).__module__, '__builtin__')
# Verify no ref leaks in Exc_str()
s = str(e)
for checkArgName in expected:
- self.assertEquals(repr(getattr(e, checkArgName)),
- repr(expected[checkArgName]),
- 'exception "%s", attribute "%s"' %
- (repr(e), checkArgName))
+ got = repr(getattr(e, checkArgName))
+ want = repr(expected[checkArgName])
+ self.assertEquals(got, want,
+ 'exception "%s", attribute %s: %r != %r' %
+ (repr(e), checkArgName, got, want))
# test for pickling support
for p in pickle, cPickle:
@@ -299,8 +281,9 @@
got = repr(getattr(new, checkArgName))
want = repr(expected[checkArgName])
self.assertEquals(got, want,
- 'pickled "%r", attribute "%s' %
- (e, checkArgName))
+ 'pickled "%r", attribute %s: '
+ '%r != %r' %
+ (e, checkArgName, got, want))
def testKeywordArgs(self):
# test that builtin exception don't take keyword args,
Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py (original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py Wed Feb 28 02:04:17 2007
@@ -14,7 +14,7 @@
self.failUnless(issubclass(Exception, object))
def verify_instance_interface(self, ins):
- for attr in ("args", "message", "__str__", "__repr__"):
+ for attr in ("message", "__str__", "__repr__"):
self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
(ins.__class__.__name__, attr))
@@ -27,7 +27,6 @@
exc_set.add(object_.__name__)
except TypeError:
pass
-
inheritance_tree = open(os.path.join(os.path.split(__file__)[0],
'exception_hierarchy.txt'))
try:
@@ -78,39 +77,37 @@
inheritance_tree.close()
self.failUnlessEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
- interface_tests = ("length", "args", "message", "str", "unicode", "repr")
+ interface_tests = ("message", "str", "unicode", "repr")
def interface_test_driver(self, results):
for test_name, (given, expected) in zip(self.interface_tests, results):
self.failUnlessEqual(given, expected, "%s: %s != %s" % (test_name,
given, expected))
+ def make_repr(self, exc, message=None):
+ """Generate the expected str/repr of an exception based on the message
+ and a converter function."""
+ name = exc.__class__.__name__
+ if message:
+ args = '(%r)' % message
+ else:
+ args = '()'
+ return name + args
+
def test_interface_single_arg(self):
# Make sure interface works properly when given a single argument
arg = "spam"
exc = Exception(arg)
- results = ([len(exc.args), 1], [exc.args[0], arg], [exc.message, arg],
- [str(exc), str(arg)], [unicode(exc), unicode(arg)],
- [repr(exc), exc.__class__.__name__ + repr(exc.args)])
- self.interface_test_driver(results)
-
- def test_interface_multi_arg(self):
- # Make sure interface correct when multiple arguments given
- arg_count = 3
- args = tuple(range(arg_count))
- exc = Exception(*args)
- results = ([len(exc.args), arg_count], [exc.args, args],
- [exc.message, ''], [str(exc), str(args)],
- [unicode(exc), unicode(args)],
- [repr(exc), exc.__class__.__name__ + repr(exc.args)])
+ results = ([exc.message, arg], [str(exc), str(arg)],
+ [unicode(exc), unicode(arg)],
+ [repr(exc), self.make_repr(exc, arg)])
self.interface_test_driver(results)
def test_interface_no_arg(self):
# Make sure that with no args that interface is correct
exc = Exception()
- results = ([len(exc.args), 0], [exc.args, tuple()], [exc.message, ''],
- [str(exc), ''], [unicode(exc), u''],
- [repr(exc), exc.__class__.__name__ + '()'])
+ results = ([exc.message, ''], [str(exc), ''], [unicode(exc), u''],
+ [repr(exc), self.make_repr(exc)])
self.interface_test_driver(results)
class UsageTests(unittest.TestCase):
Modified: python/branches/p3yk_no_args_on_exc/Misc/NEWS
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Misc/NEWS (original)
+++ python/branches/p3yk_no_args_on_exc/Misc/NEWS Wed Feb 28 02:04:17 2007
@@ -28,7 +28,13 @@
Core and Builtins
-----------------
-- Removing indexing/slicing on BaseException.
+- SyntaxError now enforces the requirement of having two arguments, second of
+ which is a four-item tuple.
+
+- EnvironmentError always binds its first argument to 'message' and 'errno'.
+ Also don't call with no more than 3 arguments.
+
+- Remove indexing/slicing on BaseException.
- Remove the exceptions module, all the exceptions are already builtin.
Modified: python/branches/p3yk_no_args_on_exc/Objects/exceptions.c
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Objects/exceptions.c (original)
+++ python/branches/p3yk_no_args_on_exc/Objects/exceptions.c Wed Feb 28 02:04:17 2007
@@ -9,8 +9,6 @@
#include "structmember.h"
#include "osdefs.h"
-#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
-
/* NOTE: If the exception class hierarchy changes, don't forget to update
* Lib/test/exception_hierarchy.txt
*/
@@ -27,12 +25,6 @@
/* the dict is created on the fly in PyObject_GenericSetAttr */
self->message = self->dict = NULL;
- self->args = PyTuple_New(0);
- if (!self->args) {
- Py_DECREF(self);
- return NULL;
- }
-
self->message = PyString_FromString("");
if (!self->message) {
Py_DECREF(self);
@@ -45,26 +37,50 @@
static int
BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
{
+ PyObject *message = NULL;
+
if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
return -1;
- Py_DECREF(self->args);
- self->args = args;
- Py_INCREF(self->args);
-
- if (PyTuple_GET_SIZE(self->args) == 1) {
- Py_CLEAR(self->message);
- self->message = PyTuple_GET_ITEM(self->args, 0);
- Py_INCREF(self->message);
+ if (!PyArg_ParseTuple(args, "|O", &message))
+ return -1;
+
+ if (message) {
+ Py_CLEAR(self->message);
+ self->message = message;
+ Py_INCREF(self->message);
}
+
return 0;
}
static int
+BaseException_super_init(PyBaseExceptionObject *self, PyObject *args,
+ PyObject *kwds)
+{
+ PyObject *short_tuple = NULL;
+ PyObject *tuple_item = NULL;
+ int ret;
+
+ /* BaseException.__init__ can handle an argument tuple of length 0 or 1. */
+ if (PyTuple_GET_SIZE(args) <= 1)
+ return BaseException_init(self, args, kwds);
+
+ short_tuple = PyTuple_New(1);
+ if (!short_tuple)
+ return -1;
+ tuple_item = PyTuple_GET_ITEM(args, 0);
+ PyTuple_SET_ITEM(short_tuple, 0, tuple_item);
+ Py_INCREF(tuple_item);
+ ret = BaseException_init(self, short_tuple, kwds);
+ Py_DECREF(short_tuple);
+ return ret;
+}
+
+static int
BaseException_clear(PyBaseExceptionObject *self)
{
Py_CLEAR(self->dict);
- Py_CLEAR(self->args);
Py_CLEAR(self->message);
return 0;
}
@@ -81,7 +97,6 @@
BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
{
Py_VISIT(self->dict);
- Py_VISIT(self->args);
Py_VISIT(self->message);
return 0;
}
@@ -89,34 +104,34 @@
static PyObject *
BaseException_str(PyBaseExceptionObject *self)
{
- PyObject *out;
-
- switch (PyTuple_GET_SIZE(self->args)) {
- case 0:
- out = PyString_FromString("");
- break;
- case 1:
- out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
- break;
- default:
- out = PyObject_Str(self->args);
- break;
- }
-
- return out;
+ return PyObject_Str(self->message);
}
static PyObject *
BaseException_repr(PyBaseExceptionObject *self)
{
PyObject *repr_suffix;
+ PyObject *message_repr;
PyObject *repr;
char *name;
char *dot;
- repr_suffix = PyObject_Repr(self->args);
- if (!repr_suffix)
- return NULL;
+ if (PyString_Check(self->message) && PyString_Size(self->message) == 0) {
+ repr_suffix = PyString_FromString("()");
+ }
+ else {
+ message_repr = PyObject_Repr(self->message);
+ if (!message_repr)
+ return NULL;
+
+ repr_suffix = PyString_FromFormat("(%s)",
+ PyString_AS_STRING(message_repr));
+ if (!repr_suffix) {
+ Py_DECREF(message_repr);
+ return NULL;
+ }
+ Py_DECREF(message_repr);
+ }
name = (char *)self->ob_type->tp_name;
dot = strrchr(name, '.');
@@ -136,10 +151,11 @@
static PyObject *
BaseException_reduce(PyBaseExceptionObject *self)
{
- if (self->args && self->dict)
- return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
+ if (self->dict)
+ return Py_BuildValue("(O, (O), O)", self->ob_type, self->message,
+ self->dict);
else
- return PyTuple_Pack(2, self->ob_type, self->args);
+ return Py_BuildValue("(O, (O))", self->ob_type, self->message);
}
/*
@@ -210,35 +226,9 @@
return 0;
}
-static PyObject *
-BaseException_get_args(PyBaseExceptionObject *self)
-{
- if (self->args == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- Py_INCREF(self->args);
- return self->args;
-}
-
-static int
-BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
-{
- PyObject *seq;
- if (val == NULL) {
- PyErr_SetString(PyExc_TypeError, "args may not be deleted");
- return -1;
- }
- seq = PySequence_Tuple(val);
- if (!seq) return -1;
- Py_CLEAR(self->args);
- self->args = seq;
- return 0;
-}
static PyGetSetDef BaseException_getset[] = {
{"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
- {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
{NULL},
};
@@ -388,7 +378,8 @@
{
Py_ssize_t size = PyTuple_GET_SIZE(args);
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
if (size == 0)
@@ -453,29 +444,26 @@
/*
* EnvironmentError extends StandardError
*/
-
-/* Where a function has a single filename, such as open() or some
- * of the os module functions, PyErr_SetFromErrnoWithFilename() is
- * called, giving a third argument which is the filename. But, so
- * that old code using in-place unpacking doesn't break, e.g.:
- *
- * except IOError, (errno, strerror):
- *
- * we hack args so that it only contains two items. This also
- * means we need our own __str__() which prints out the filename
- * when it was supplied.
- */
static int
EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
PyObject *kwds)
{
PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
- PyObject *subslice = NULL;
+ Py_ssize_t args_len = 0;
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
- if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
+ args_len = PyTuple_GET_SIZE(args);
+
+ if (args_len == 0 || args_len == 1) {
+ Py_INCREF(self->message);
+ self->myerrno = self->message;
+ Py_INCREF(Py_None);
+ self->strerror = Py_None;
+ Py_INCREF(Py_None);
+ self->filename = Py_None;
return 0;
}
@@ -496,13 +484,10 @@
Py_CLEAR(self->filename); /* replacing */
self->filename = filename;
Py_INCREF(self->filename);
-
- subslice = PyTuple_GetSlice(args, 0, 2);
- if (!subslice)
- return -1;
-
- Py_DECREF(self->args); /* replacing args */
- self->args = subslice;
+ }
+ else {
+ Py_INCREF(Py_None);
+ self->filename = Py_None;
}
return 0;
}
@@ -560,22 +545,11 @@
return NULL;
}
- if (self->myerrno) {
- Py_INCREF(self->myerrno);
- PyTuple_SET_ITEM(tuple, 0, self->myerrno);
- }
- else {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(tuple, 0, Py_None);
- }
- if (self->strerror) {
- Py_INCREF(self->strerror);
- PyTuple_SET_ITEM(tuple, 1, self->strerror);
- }
- else {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(tuple, 1, Py_None);
- }
+ Py_INCREF(self->myerrno);
+ PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(tuple, 1, self->strerror);
PyTuple_SET_ITEM(tuple, 2, repr);
@@ -642,27 +616,26 @@
static PyObject *
EnvironmentError_reduce(PyEnvironmentErrorObject *self)
{
- PyObject *args = self->args;
- PyObject *res = NULL, *tmp;
+ PyObject *args = PyTuple_New(3);
+ PyObject *res = NULL;
+
+ if (!args)
+ return NULL;
+
+ if (self->myerrno == Py_None) {
+ Py_INCREF(self->message);
+ PyTuple_SET_ITEM(args, 0, self->message);
+ }
+ else {
+ Py_INCREF(self->myerrno);
+ PyTuple_SET_ITEM(args, 0, self->myerrno);
+ }
- /* self->args is only the first two real arguments if there was a
- * file name given to EnvironmentError. */
- if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
- args = PyTuple_New(3);
- if (!args) return NULL;
-
- tmp = PyTuple_GET_ITEM(self->args, 0);
- Py_INCREF(tmp);
- PyTuple_SET_ITEM(args, 0, tmp);
-
- tmp = PyTuple_GET_ITEM(self->args, 1);
- Py_INCREF(tmp);
- PyTuple_SET_ITEM(args, 1, tmp);
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(args, 1, self->strerror);
Py_INCREF(self->filename);
PyTuple_SET_ITEM(args, 2, self->filename);
- } else
- Py_INCREF(args);
if (self->dict)
res = PyTuple_Pack(3, self->ob_type, args, self->dict);
@@ -938,15 +911,25 @@
PyObject *info = NULL;
Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
- if (lenargs >= 1) {
- Py_CLEAR(self->msg);
- self->msg = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(self->msg);
+ Py_CLEAR(self->msg);
+ self->msg = self->message;
+ Py_INCREF(self->msg);
+
+ if (lenargs == 1) {
+ Py_INCREF(Py_None);
+ self->filename = Py_None;
+ Py_INCREF(Py_None);
+ self->lineno = Py_None;
+ Py_INCREF(Py_None);
+ self->offset = Py_None;
+ Py_INCREF(Py_None);
+ self->text = Py_None;
}
- if (lenargs == 2) {
+ else if (lenargs == 2) {
info = PyTuple_GET_ITEM(args, 1);
info = PySequence_Tuple(info);
if (!info) return -1;
@@ -976,6 +959,10 @@
Py_DECREF(info);
}
+ else {
+ PyErr_SetString(PyExc_TypeError, "expect either 0, 1, or 2 arguments");
+ return -1;
+ }
return 0;
}
@@ -1091,6 +1078,26 @@
return result;
}
+
+static PyObject *
+SyntaxError_reduce(PySyntaxErrorObject *self)
+{
+ if (self->dict)
+ return Py_BuildValue("(O, (O, (O, O, O, O)), O)", self->ob_type,
+ self->message, self->filename, self->lineno,
+ self->offset, self->text, self->dict);
+ else
+ return Py_BuildValue("(O, (O, (O, O, O, O)))", self->ob_type,
+ self->message, self->filename, self->lineno,
+ self->offset, self->text);
+}
+
+
+static PyMethodDef SyntaxError_methods[] = {
+ {"__reduce__", (PyCFunction)SyntaxError_reduce, METH_NOARGS},
+ {NULL}
+};
+
static PyMemberDef SyntaxError_members[] = {
{"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
PyDoc_STR("exception message")},
@@ -1110,9 +1117,11 @@
{NULL} /* Sentinel */
};
+
ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
- SyntaxError_dealloc, 0, SyntaxError_members,
- SyntaxError_str, "Invalid syntax.");
+ SyntaxError_dealloc, SyntaxError_methods,
+ SyntaxError_members, SyntaxError_str,
+ "Invalid syntax.");
/*
@@ -1158,9 +1167,9 @@
string, that string will be displayed in quotes. Too bad.
If args is anything else, use the default BaseException__str__().
*/
- if (PyTuple_GET_SIZE(self->args) == 1) {
- return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
- }
+ if (PyString_Check(self->message) && PyString_Size(self->message) == 0)
+ return PyObject_Repr(self->message);
+
return BaseException_str(self);
}
@@ -1549,7 +1558,8 @@
static int
UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
return UnicodeError_init((PyUnicodeErrorObject *)self, args,
kwds, &PyUnicode_Type);
@@ -1625,7 +1635,8 @@
static int
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
return UnicodeError_init((PyUnicodeErrorObject *)self, args,
kwds, &PyString_Type);
@@ -1701,7 +1712,8 @@
UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
PyObject *kwds)
{
- if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+ -1)
return -1;
Py_CLEAR(self->object);
1
0
Author: brett.cannon
Date: Wed Feb 28 01:56:00 2007
New Revision: 54012
Modified:
python/branches/p3yk_no_args_on_exc/ (props changed)
Log:
svnmerge init.
1
0
Author: brett.cannon
Date: Wed Feb 28 01:41:10 2007
New Revision: 54011
Added:
python/branches/p3yk_no_args_on_exc/
- copied from r54010, python/branches/p3yk/
Log:
Start a branch for working on removing the 'args' attribute from BaseException
(assuming I don't lose my sanity before the work is done).
1
0

r54007 - in sandbox/trunk/2to3: README fixer_tests.py test.py tests tests.py tests/__init__.py tests/support.py tests/test_fixers.py tests/test_pytree.py
by collin.winter Feb. 27, 2007
by collin.winter Feb. 27, 2007
Feb. 27, 2007
Author: collin.winter
Date: Wed Feb 28 00:45:47 2007
New Revision: 54007
Added:
sandbox/trunk/2to3/test.py (contents, props changed)
sandbox/trunk/2to3/tests/ (props changed)
sandbox/trunk/2to3/tests/__init__.py (contents, props changed)
sandbox/trunk/2to3/tests/support.py (contents, props changed)
sandbox/trunk/2to3/tests/test_fixers.py
- copied, changed from r53996, sandbox/trunk/2to3/fixer_tests.py
sandbox/trunk/2to3/tests/test_pytree.py
- copied, changed from r53996, sandbox/trunk/2to3/tests.py
Removed:
sandbox/trunk/2to3/fixer_tests.py
sandbox/trunk/2to3/tests.py
Modified:
sandbox/trunk/2to3/README
Log:
Move tests.py and fixer_tests.py into tests/, add testing infrastructure.
Modified: sandbox/trunk/2to3/README
==============================================================================
--- sandbox/trunk/2to3/README (original)
+++ sandbox/trunk/2to3/README Wed Feb 28 00:45:47 2007
@@ -5,8 +5,8 @@
Files:
README - this file
+test.py - runs all unittests for 2to3
play.py - program to exercise the idempotency of pytree nodes
-tests.py - unit tests for pytree.py
patcomp.py - pattern compiler
pytree.py - parse tree nodes (not specific to Python, despite the name!)
pygram.py - code specific to the Python grammar
@@ -17,6 +17,7 @@
PatternGrammar.pickle - pickled pattern grammar tables (generated file)
pgen2/ - Parser generator and driver (1) (2)
fixes/ - Individual transformations
+tests/ - Test files for pytree, fixers, grammar, etc
Notes:
Deleted: /sandbox/trunk/2to3/fixer_tests.py
==============================================================================
--- /sandbox/trunk/2to3/fixer_tests.py Wed Feb 28 00:45:47 2007
+++ (empty file)
@@ -1,1126 +0,0 @@
-#!/usr/bin/env python2.5
-""" Test suite for the fixer modules """
-# Author: Collin Winter
-
-# Python imports
-from StringIO import StringIO
-import re
-import unittest
-import logging
-
-# Local imports
-import pytree
-import refactor
-
-skip_whitespace = re.compile(r"""\S""")
-
-def reformat(string):
- indent = re.search(skip_whitespace, string).start()
- if indent == 0:
- code = string
- else:
- code = "\n".join(line[indent-1:] for line in string.split("\n")[1:])
- return code + "\n\n"
-
-# We wrap the RefactoringTool's fixer objects so we can intercept
-# the call to set_filename() and so modify the fixers' logging objects.
-# This allows us to make sure that certain code chunks produce certain
-# warnings.
-class Fixer(object):
- def __init__(self, fixer, handler):
- self.fixer = fixer
- self.handler = handler
-
- def __getattr__(self, attr):
- return getattr(self.fixer, attr)
-
- def set_filename(self, filename):
- self.fixer.set_filename(filename)
- self.fixer.logger.addHandler(self.handler)
-
-class Options:
- def __init__(self, **kwargs):
- for k, v in kwargs.items():
- setattr(self, k, v)
-
- self.verbose = False
-
-class FixerTestCase(unittest.TestCase):
- def setUp(self):
- options = Options(fix=[self.fixer], print_function=False)
- self.refactor = refactor.RefactoringTool(options)
-
- self.logging_stream = StringIO()
- sh = logging.StreamHandler(self.logging_stream)
- sh.setFormatter(logging.Formatter("%(message)s"))
- self.refactor.fixers = [Fixer(f, sh) for f in self.refactor.fixers]
-
- def check(self, before, after):
- before = reformat(before)
- after = reformat(after)
- refactored = self.refactor_stream("<string>", StringIO(before))
- self.failUnlessEqual(after, refactored)
-
- def warns(self, before, after, message):
- self.check(before, after)
-
- self.failUnless(message in self.logging_stream.getvalue())
-
- def refactor_stream(self, stream_name, stream):
- try:
- tree = self.refactor.driver.parse_stream(stream)
- except Exception, err:
- raise
- self.log_error("Can't parse %s: %s: %s",
- filename, err.__class__.__name__, err)
- return
- self.refactor.refactor_tree(tree, stream_name)
- return str(tree)
-
-
-class Test_ne(FixerTestCase):
- fixer = "ne"
-
- def test_1(self):
- b = """if x <> y:
- pass"""
-
- a = """if x != y:
- pass"""
- self.check(b, a)
-
- def test_2(self):
- b = """if x<>y:
- pass"""
-
- a = """if x!=y:
- pass"""
- self.check(b, a)
-
- def test_3(self):
- b = """if x<>y<>z:
- pass"""
-
- a = """if x!=y!=z:
- pass"""
- self.check(b, a)
-
-class Test_has_key(FixerTestCase):
- fixer = "has_key"
-
- def test_1(self):
- b = """x = d.has_key("x") or d.has_key("y")"""
- a = """x = "x" in d or "y" in d"""
- self.check(b, a)
-
- def test_2(self):
- b = """x = a.b.c.d.has_key("x") ** 3"""
- a = """x = ("x" in a.b.c.d) ** 3"""
- self.check(b, a)
-
- def test_3(self):
- b = """x = a.b.has_key(1 + 2).__repr__()"""
- a = """x = (1 + 2 in a.b).__repr__()"""
- self.check(b, a)
-
- def test_4(self):
- b = """x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4"""
- a = """x = (1 + 2 in a.b).__repr__() ** -3 ** 4"""
- self.check(b, a)
-
- def test_5(self):
- b = """x = a.has_key(f or g)"""
- a = """x = (f or g) in a"""
- self.check(b, a)
-
- def test_6(self):
- b = """x = a + b.has_key(c)"""
- a = """x = a + (c in b)"""
- self.check(b, a)
-
- def test_7(self):
- b = """x = a.has_key(lambda: 12)"""
- a = """x = (lambda: 12) in a"""
- self.check(b, a)
-
- def test_8(self):
- b = """x = a.has_key(a for a in b)"""
- a = """x = (a for a in b) in a"""
- self.check(b, a)
-
- def test_9(self):
- b = """if not a.has_key(b): pass"""
- a = """if b not in a: pass"""
- self.check(b, a)
-
- def test_10(self):
- b = """if not a.has_key(b).__repr__(): pass"""
- a = """if not (b in a).__repr__(): pass"""
- self.check(b, a)
-
- def test_11(self):
- b = """if not a.has_key(b) ** 2: pass"""
- a = """if not (b in a) ** 2: pass"""
- self.check(b, a)
-
-class Test_apply(FixerTestCase):
- fixer = "apply"
-
- def test_1(self):
- b = """x = apply(f, g + h)"""
- a = """x = f(*g + h)"""
- self.check(b, a)
-
- def test_2(self):
- b = """y = apply(f, g, h)"""
- a = """y = f(*g, **h)"""
- self.check(b, a)
-
- def test_3(self):
- b = """z = apply(fs[0], g or h, h or g)"""
- a = """z = fs[0](*g or h, **h or g)"""
- self.check(b, a)
-
- def test_4(self):
- b = """apply(f, (x, y) + t)"""
- a = """f(*(x, y) + t)"""
- self.check(b, a)
-
- def test_5(self):
- b = """apply(f, args,)"""
- a = """f(*args)"""
- self.check(b, a)
-
- def test_6(self):
- b = """apply(f, args, kwds,)"""
- a = """f(*args, **kwds)"""
- self.check(b, a)
-
- # Test that complex functions are parenthesized
-
- def test_7(self):
- b = """x = apply(f+g, args)"""
- a = """x = (f+g)(*args)"""
- self.check(b, a)
-
- def test_8(self):
- b = """x = apply(f*g, args)"""
- a = """x = (f*g)(*args)"""
- self.check(b, a)
-
- def test_9(self):
- b = """x = apply(f**g, args)"""
- a = """x = (f**g)(*args)"""
- self.check(b, a)
-
- # But dotted names etc. not
-
- def test_10(self):
- b = """x = apply(f.g, args)"""
- a = """x = f.g(*args)"""
- self.check(b, a)
-
- def test_11(self):
- b = """x = apply(f[x], args)"""
- a = """x = f[x](*args)"""
- self.check(b, a)
-
- def test_12(self):
- b = """x = apply(f(), args)"""
- a = """x = f()(*args)"""
- self.check(b, a)
-
- # Extreme case
- def test_13(self):
- b = """x = apply(a.b.c.d.e.f, args, kwds)"""
- a = """x = a.b.c.d.e.f(*args, **kwds)"""
- self.check(b, a)
-
- # XXX Comments in weird places still get lost
- def test_14(self):
- b = """apply( # foo
- f, # bar
- args)"""
- a = """f(*args)"""
- self.check(b, a)
-
- # These should *not* be touched
-
- def test_15(self):
- b = """apply()"""
- a = """apply()"""
- self.check(b, a)
-
- def test_16(self):
- b = """apply(f)"""
- a = """apply(f)"""
- self.check(b, a)
-
- def test_17(self):
- b = """apply(f,)"""
- a = """apply(f,)"""
- self.check(b, a)
-
- def test_18(self):
- b = """apply(f, args, kwds, extras)"""
- a = """apply(f, args, kwds, extras)"""
- self.check(b, a)
-
- def test_19(self):
- b = """apply(f, *args, **kwds)"""
- a = """apply(f, *args, **kwds)"""
- self.check(b, a)
-
- def test_20(self):
- b = """apply(f, *args)"""
- a = """apply(f, *args)"""
- self.check(b, a)
-
- def test_21(self):
- b = """apply(func=f, args=args, kwds=kwds)"""
- a = """apply(func=f, args=args, kwds=kwds)"""
- self.check(b, a)
-
- def test_22(self):
- b = """apply(f, args=args, kwds=kwds)"""
- a = """apply(f, args=args, kwds=kwds)"""
- self.check(b, a)
-
- def test_23(self):
- b = """apply(f, args, kwds=kwds)"""
- a = """apply(f, args, kwds=kwds)"""
- self.check(b, a)
-
-
-class Test_intern(FixerTestCase):
- fixer = "intern"
-
- def test_1(self):
- b = """x = intern(a)"""
- a = """x = sys.intern(a)"""
- self.check(b, a)
-
- def test_2(self):
- b = """y = intern("b" # test
- )"""
- a = """y = sys.intern("b" # test
- )"""
- self.check(b, a)
-
- def test_3(self):
- b = """z = intern(a+b+c.d,)"""
- a = """z = sys.intern(a+b+c.d,)"""
- self.check(b, a)
-
- def test_4(self):
- b = """intern("y%s" % 5).replace("y", "")"""
- a = """sys.intern("y%s" % 5).replace("y", "")"""
- self.check(b, a)
-
- # These should not be refactored
-
- def test_5(self):
- b = """intern(a=1)"""
- a = """intern(a=1)"""
- self.check(b, a)
-
- def test_6(self):
- b = """intern(f, g)"""
- a = """intern(f, g)"""
- self.check(b, a)
-
- def test_7(self):
- b = """intern(*h)"""
- a = """intern(*h)"""
- self.check(b, a)
-
- def test_8(self):
- b = """intern(**i)"""
- a = """intern(**i)"""
- self.check(b, a)
-
-class Test_print(FixerTestCase):
- fixer = "print"
-
- def test_1(self):
- b = """print 1, 1+1, 1+1+1"""
- a = """print(1, 1+1, 1+1+1)"""
- self.check(b, a)
-
- def test_2(self):
- b = """print 1, 2"""
- a = """print(1, 2)"""
- self.check(b, a)
-
- def test_3(self):
- b = """print"""
- a = """print()"""
- self.check(b, a)
-
- # trailing commas
-
- def test_4(self):
- b = """print 1, 2, 3,"""
- a = """print(1, 2, 3, end=' ')"""
- self.check(b, a)
-
- def test_5(self):
- b = """print 1, 2,"""
- a = """print(1, 2, end=' ')"""
- self.check(b, a)
-
- def test_6(self):
- b = """print 1,"""
- a = """print(1, end=' ')"""
- self.check(b, a)
-
- # >> stuff
-
- # no trailing comma
- def test_7(self):
- b = """print >>sys.stderr, 1, 2, 3"""
- a = """print(1, 2, 3, file=sys.stderr)"""
- self.check(b, a)
-
- # trailing comma
- def test_8(self):
- b = """print >>sys.stderr, 1, 2,"""
- a = """print(1, 2, end=' ', file=sys.stderr)"""
- self.check(b, a)
-
- # no trailing comma
- def test_9(self):
- b = """print >>sys.stderr, 1+1"""
- a = """print(1+1, file=sys.stderr)"""
- self.check(b, a)
-
- # spaces before sys.stderr
- def test_10(self):
- b = """print >> sys.stderr"""
- a = """print(file=sys.stderr)"""
- self.check(b, a)
-
-
-class Test_exec(FixerTestCase):
- fixer = "exec"
-
- def test_1(self):
- b = """exec code"""
- a = """exec(code)"""
- self.check(b, a)
-
- def test_2(self):
- b = """exec code in ns"""
- a = """exec(code, ns)"""
- self.check(b, a)
-
- def test_3(self):
- b = """exec code in ns1, ns2"""
- a = """exec(code, ns1, ns2)"""
- self.check(b, a)
-
- def test_4(self):
- b = """exec (a.b()) in ns"""
- a = """exec((a.b()), ns)"""
- self.check(b, a)
-
- def test_5(self):
- b = """exec a.b() + c in ns"""
- a = """exec(a.b() + c, ns)"""
- self.check(b, a)
-
- # These should not be touched
-
- def test_6(self):
- b = """exec(code)"""
- a = """exec(code)"""
- self.check(b, a)
-
- def test_7(self):
- b = """exec (code)"""
- a = """exec (code)"""
- self.check(b, a)
-
- def test_8(self):
- b = """exec(code, ns)"""
- a = """exec(code, ns)"""
- self.check(b, a)
-
- def test_9(self):
- b = """exec(code, ns1, ns2)"""
- a = """exec(code, ns1, ns2)"""
- self.check(b, a)
-
-
-class Test_repr(FixerTestCase):
- fixer = "repr"
-
- def test_1(self):
- b = """x = `1 + 2`"""
- a = """x = repr(1 + 2)"""
- self.check(b, a)
-
- def test_2(self):
- b = """y = `x`"""
- a = """y = repr(x)"""
- self.check(b, a)
-
- def test_3(self):
- b = """z = `y`.__repr__()"""
- a = """z = repr(y).__repr__()"""
- self.check(b, a)
-
- def test_4(self):
- b = """x = `1, 2, 3`"""
- a = """x = repr((1, 2, 3))"""
- self.check(b, a)
-
- def test_5(self):
- b = """x = `1 + `2``"""
- a = """x = repr(1 + repr(2))"""
- self.check(b, a)
-
- def test_6(self):
- b = """x = `1, 2 + `3, 4``"""
- a = """x = repr((1, 2 + repr((3, 4))))"""
- self.check(b, a)
-
-class Test_except(FixerTestCase):
- fixer = "except"
-
- def test_1(self):
- b = """
- def foo():
- try:
- pass
- except Exception, (f, e):
- pass
- except ImportError, e:
- pass"""
-
- a = """
- def foo():
- try:
- pass
- except Exception as xxx_todo_changeme:
- (f, e) = xxx_todo_changeme.message
- pass
- except ImportError as e:
- pass"""
- self.check(b, a)
-
- def test_2(self):
- b = """
- try:
- pass
- except (RuntimeError, ImportError), e:
- pass"""
-
- a = """
- try:
- pass
- except (RuntimeError, ImportError) as e:
- pass"""
- self.check(b, a)
-
- def test_3(self):
- b = """
- try:
- pass
- except Exception, (a, b):
- pass"""
-
- a = """
- try:
- pass
- except Exception as xxx_todo_changeme1:
- (a, b) = xxx_todo_changeme1.message
- pass"""
- self.check(b, a)
-
- def test_4(self):
- b = """
- try:
- pass
- except Exception, d[5]:
- pass"""
-
- a = """
- try:
- pass
- except Exception as xxx_todo_changeme2:
- d[5] = xxx_todo_changeme2
- pass"""
- self.check(b, a)
-
- def test_5(self):
- b = """
- try:
- pass
- except Exception, a.foo:
- pass"""
-
- a = """
- try:
- pass
- except Exception as xxx_todo_changeme3:
- a.foo = xxx_todo_changeme3
- pass"""
- self.check(b, a)
-
- def test_6(self):
- b = """
- try:
- pass
- except Exception, a().foo:
- pass"""
-
- a = """
- try:
- pass
- except Exception as xxx_todo_changeme4:
- a().foo = xxx_todo_changeme4
- pass"""
- self.check(b, a)
-
- # These should not be touched:
-
- def test_7(self):
- b = """
- try:
- pass
- except:
- pass"""
-
- a = """
- try:
- pass
- except:
- pass"""
- self.check(b, a)
-
- def test_8(self):
- b = """
- try:
- pass
- except Exception:
- pass"""
-
- a = """
- try:
- pass
- except Exception:
- pass"""
- self.check(b, a)
-
- def test_9(self):
- b = """
- try:
- pass
- except (Exception, SystemExit):
- pass"""
-
- a = """
- try:
- pass
- except (Exception, SystemExit):
- pass"""
- self.check(b, a)
-
-
-class Test_raise(FixerTestCase):
- fixer = "raise"
-
- def test_1(self):
- b = """raise Exception, 5"""
- a = """raise Exception(5)"""
- self.check(b, a)
-
- def test_2(self):
- b = """raise Exception,5"""
- a = """raise Exception(5)"""
- self.check(b, a)
-
- def test_3(self):
- b = """raise Exception, (5, 6, 7)"""
- a = """raise Exception(5, 6, 7)"""
- self.check(b, a)
-
- def test_4(self):
- b = """raise E, (5, 6) % (a, b)"""
- a = """raise E((5, 6) % (a, b))"""
- self.check(b, a)
-
- def test_5(self):
- b = """raise (((E1, E2), E3), E4), V"""
- a = """raise E1(V)"""
- self.check(b, a)
-
- def test_6(self):
- b = """raise (E1, (E2, E3), E4), V"""
- a = """raise E1(V)"""
- self.check(b, a)
-
- # These should produce a warning
-
- def test_warn_1(self):
- s = """raise 'foo'"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- def test_warn_2(self):
- s = """raise "foo", 5"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- def test_warn_3(self):
- s = """raise "foo", 5, 6"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- # These should result in traceback-assignment
-
- def test_tb_1(self):
- b = """def foo():
- raise Exception, 5, 6"""
- a = """def foo():
- raise Exception(5).with_traceback(6)"""
- self.check(b, a)
-
- def test_tb_2(self):
- b = """def foo():
- a = 5
- raise Exception, 5, 6
- b = 6"""
- a = """def foo():
- a = 5
- raise Exception(5).with_traceback(6)
- b = 6"""
- self.check(b, a)
-
- def test_tb_3(self):
- b = """def foo():
- raise Exception,5,6"""
- a = """def foo():
- raise Exception(5).with_traceback(6)"""
- self.check(b, a)
-
- def test_tb_4(self):
- b = """def foo():
- a = 5
- raise Exception,5,6
- b = 6"""
- a = """def foo():
- a = 5
- raise Exception(5).with_traceback(6)
- b = 6"""
- self.check(b, a)
-
- def test_tb_5(self):
- b = """def foo():
- raise Exception, (5, 6, 7), 6"""
- a = """def foo():
- raise Exception(5, 6, 7).with_traceback(6)"""
- self.check(b, a)
-
- def test_tb_6(self):
- b = """def foo():
- a = 5
- raise Exception, (5, 6, 7), 6
- b = 6"""
- a = """def foo():
- a = 5
- raise Exception(5, 6, 7).with_traceback(6)
- b = 6"""
- self.check(b, a)
-
-
-class Test_throw(FixerTestCase):
- fixer = "throw"
-
- def test_1(self):
- b = """g.throw(Exception, 5)"""
- a = """g.throw(Exception(5))"""
- self.check(b, a)
-
- def test_2(self):
- b = """g.throw(Exception,5)"""
- a = """g.throw(Exception(5))"""
- self.check(b, a)
-
- def test_3(self):
- b = """g.throw(Exception, (5, 6, 7))"""
- a = """g.throw(Exception(5, 6, 7))"""
- self.check(b, a)
-
- def test_4(self):
- b = """5 + g.throw(Exception, 5)"""
- a = """5 + g.throw(Exception(5))"""
- self.check(b, a)
-
- # These should produce warnings
-
- def test_warn_1(self):
- s = """g.throw("foo")"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- def test_warn_2(self):
- s = """g.throw("foo", 5)"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- def test_warn_3(self):
- s = """g.throw("foo", 5, 6)"""
- self.warns(s, s, "Python 3 does not support string exceptions")
-
- # These should not be touched
-
- def test_untouched_1(self):
- b = """g.throw(Exception)"""
- a = """g.throw(Exception)"""
- self.check(b, a)
-
- def test_untouched_2(self):
- b = """g.throw(Exception(5, 6))"""
- a = """g.throw(Exception(5, 6))"""
- self.check(b, a)
-
- def test_untouched_3(self):
- b = """5 + g.throw(Exception(5, 6))"""
- a = """5 + g.throw(Exception(5, 6))"""
- self.check(b, a)
-
- # These should result in traceback-assignment
-
- def test_tb_1(self):
- b = """def foo():
- g.throw(Exception, 5, 6)"""
- a = """def foo():
- g.throw(Exception(5).with_traceback(6))"""
- self.check(b, a)
-
- def test_tb_2(self):
- b = """def foo():
- a = 5
- g.throw(Exception, 5, 6)
- b = 6"""
- a = """def foo():
- a = 5
- g.throw(Exception(5).with_traceback(6))
- b = 6"""
- self.check(b, a)
-
- def test_tb_3(self):
- b = """def foo():
- g.throw(Exception,5,6)"""
- a = """def foo():
- g.throw(Exception(5).with_traceback(6))"""
- self.check(b, a)
-
- def test_tb_4(self):
- b = """def foo():
- a = 5
- g.throw(Exception,5,6)
- b = 6"""
- a = """def foo():
- a = 5
- g.throw(Exception(5).with_traceback(6))
- b = 6"""
- self.check(b, a)
-
- def test_tb_5(self):
- b = """def foo():
- g.throw(Exception, (5, 6, 7), 6)"""
- a = """def foo():
- g.throw(Exception(5, 6, 7).with_traceback(6))"""
- self.check(b, a)
-
- def test_tb_6(self):
- b = """def foo():
- a = 5
- g.throw(Exception, (5, 6, 7), 6)
- b = 6"""
- a = """def foo():
- a = 5
- g.throw(Exception(5, 6, 7).with_traceback(6))
- b = 6"""
- self.check(b, a)
-
- def test_tb_7(self):
- b = """def foo():
- a + g.throw(Exception, 5, 6)"""
- a = """def foo():
- a + g.throw(Exception(5).with_traceback(6))"""
- self.check(b, a)
-
- def test_tb_8(self):
- b = """def foo():
- a = 5
- a + g.throw(Exception, 5, 6)
- b = 6"""
- a = """def foo():
- a = 5
- a + g.throw(Exception(5).with_traceback(6))
- b = 6"""
- self.check(b, a)
-
-
-class Test_long(FixerTestCase):
- fixer = "long"
-
- def test_1(self):
- b = """x = long(x)"""
- a = """x = int(x)"""
- self.check(b, a)
-
- def test_2(self):
- b = """y = isinstance(x, long)"""
- a = """y = isinstance(x, int)"""
- self.check(b, a)
-
- def test_3(self):
- b = """z = type(x) in (int, long)"""
- a = """z = type(x) in (int, int)"""
- self.check(b, a)
-
- def test_4(self):
- b = """a = 12L"""
- a = """a = 12"""
- self.check(b, a)
-
- def test_5(self):
- b = """b = 0x12l"""
- a = """b = 0x12"""
- self.check(b, a)
-
- # These should not be touched
-
- def test_6(self):
- b = """a = 12"""
- a = """a = 12"""
- self.check(b, a)
-
- def test_7(self):
- b = """b = 0x12"""
- a = """b = 0x12"""
- self.check(b, a)
-
- def test_8(self):
- b = """c = 3.14"""
- a = """c = 3.14"""
- self.check(b, a)
-
-
-class Test_sysexcinfo(FixerTestCase):
- fixer = "sysexcinfo"
-
- def test_1(self):
- s = """sys.exc_info()"""
- self.warns(s, s, "This function is going away")
-
- def test_2(self):
- s = """if sys.exc_info()[1] == 1:
- pass"""
-
- self.warns(s, s, "This function is going away")
-
- def test_3(self):
- s = """f = sys.exc_info"""
- self.warns(s, s, "This function is going away")
-
- def test_4(self):
- s = """f = sys.exc_type + ":" + sys.exc_value"""
- self.warns(s, s, "This attribute is going away")
-
-
-class Test_dict(FixerTestCase):
- fixer = "dict"
-
- def test_01(self):
- b = "d.keys()"
- a = "list(d.keys())"
- self.check(b, a)
-
- def test_01a(self):
- b = "a[0].foo().keys()"
- a = "list(a[0].foo().keys())"
- self.check(b, a)
-
- def test_02(self):
- b = "d.items()"
- a = "list(d.items())"
- self.check(b, a)
-
- def test_03(self):
- b = "d.values()"
- a = "list(d.values())"
- self.check(b, a)
-
- def test_04(self):
- b = "d.iterkeys()"
- a = "iter(d.keys())"
- self.check(b, a)
-
- def test_05(self):
- b = "d.iteritems()"
- a = "iter(d.items())"
- self.check(b, a)
-
- def test_06(self):
- b = "d.itervalues()"
- a = "iter(d.values())"
- self.check(b, a)
-
- def test_07(self):
- b = "list(d.keys())"
- a = b
- self.check(b, a)
-
- def test_08(self):
- b = "sorted(d.keys())"
- a = b
- self.check(b, a)
-
- def test_09(self):
- b = "iter(d.keys())"
- a = "iter(list(d.keys()))"
- self.check(b, a)
-
- def test_10(self):
- b = "foo(d.keys())"
- a = "foo(list(d.keys()))"
- self.check(b, a)
-
- def test_11(self):
- b = "for i in d.keys(): print i"
- a = "for i in list(d.keys()): print i"
- self.check(b, a)
-
- def test_12(self):
- b = "for i in d.iterkeys(): print i"
- a = "for i in d.keys(): print i"
- self.check(b, a)
-
- def test_13(self):
- b = "[i for i in d.keys()]"
- a = "[i for i in list(d.keys())]"
- self.check(b, a)
-
- def test_14(self):
- b = "[i for i in d.iterkeys()]"
- a = "[i for i in d.keys()]"
- self.check(b, a)
-
- def test_15(self):
- b = "(i for i in d.keys())"
- a = "(i for i in list(d.keys()))"
- self.check(b, a)
-
- def test_16(self):
- b = "(i for i in d.iterkeys())"
- a = "(i for i in d.keys())"
- self.check(b, a)
-
- def test_17(self):
- b = "iter(d.iterkeys())"
- a = "iter(d.keys())"
- self.check(b, a)
-
- def test_18(self):
- b = "list(d.iterkeys())"
- a = "list(d.keys())"
- self.check(b, a)
-
- def test_19(self):
- b = "sorted(d.iterkeys())"
- a = "sorted(d.keys())"
- self.check(b, a)
-
- def test_20(self):
- b = "foo(d.iterkeys())"
- a = "foo(iter(d.keys()))"
- self.check(b, a)
-
- def test_21(self):
- b = "print h.iterkeys().next()"
- a = "print iter(h.keys()).next()"
- self.check(b, a)
-
- def test_22(self):
- b = "print h.keys()[0]"
- a = "print list(h.keys())[0]"
- self.check(b, a)
-
- def test_23(self):
- b = "print list(h.iterkeys().next())"
- a = "print list(iter(h.keys()).next())"
- self.check(b, a)
-
- def test_24(self):
- b = "for x in h.keys()[0]: print x"
- a = "for x in list(h.keys())[0]: print x"
- self.check(b, a)
-
-class Test_xrange(FixerTestCase):
- fixer = "xrange"
-
- def test_1(self):
- b = """x = xrange(10)"""
- a = """x = range(10)"""
- self.check(b, a)
-
- def test_2(self):
- b = """x = xrange(1, 10)"""
- a = """x = range(1, 10)"""
- self.check(b, a)
-
- def test_3(self):
- b = """x = xrange(0, 10, 2)"""
- a = """x = range(0, 10, 2)"""
- self.check(b, a)
-
- def test_4(self):
- b = """for i in xrange(10):\n j=i"""
- a = """for i in range(10):\n j=i"""
- self.check(b, a)
-
-
-class Test_raw_input(FixerTestCase):
- fixer = "raw_input"
-
- def test_1(self):
- b = """x = raw_input()"""
- a = """x = input()"""
- self.check(b, a)
-
- def test_2(self):
- b = """x = raw_input('')"""
- a = """x = input('')"""
- self.check(b, a)
-
- def test_3(self):
- b = """x = raw_input('prompt')"""
- a = """x = input('prompt')"""
- self.check(b, a)
-
-
-class Test_input(FixerTestCase):
- fixer = "input"
-
- def test_1(self):
- b = """x = input()"""
- a = """x = eval(input())"""
- self.check(b, a)
-
- def test_2(self):
- b = """x = input('')"""
- a = """x = eval(input(''))"""
- self.check(b, a)
-
- def test_3(self):
- b = """x = input('prompt')"""
- a = """x = eval(input('prompt'))"""
- self.check(b, a)
-
-
-if __name__ == "__main__":
- import sys
- if not sys.argv[1:]:
- sys.argv.append("-v")
- unittest.main()
Added: sandbox/trunk/2to3/test.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/2to3/test.py Wed Feb 28 00:45:47 2007
@@ -0,0 +1,8 @@
+"""Main test file for 2to3. Running "python test.py" will run all
+tests in tests/test_*.py."""
+# Author: Collin Winter
+
+import tests
+import tests.support
+
+tests.support.run_all_tests(tests=tests.all_tests)
Deleted: /sandbox/trunk/2to3/tests.py
==============================================================================
--- /sandbox/trunk/2to3/tests.py Wed Feb 28 00:45:47 2007
+++ (empty file)
@@ -1,239 +0,0 @@
-#!/usr/bin/env python2.5
-# Copyright 2006 Google, Inc. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-"""Unit tests for pytree.py.
-
-NOTE: Please *don't* add doc strings to individual test methods!
-In verbose mode, printing of the module, class and method name is much
-more helpful than printing of (the first line of) the docstring,
-especially when debugging a test.
-"""
-
-# Python imports
-import unittest
-
-# Local imports (XXX should become a package)
-import pytree
-
-
-class TestNodes(unittest.TestCase):
-
- """Unit tests for nodes (Base, Leaf, Node)."""
-
- def testBaseCantConstruct(self):
- if __debug__:
- # Test that instantiating Base() raises an AssertionError
- self.assertRaises(AssertionError, pytree.Base)
-
- def testLeaf(self):
- l1 = pytree.Leaf(100, "foo")
- self.assertEqual(l1.type, 100)
- self.assertEqual(l1.value, "foo")
-
- def testLeafRepr(self):
- l1 = pytree.Leaf(100, "foo")
- self.assertEqual(repr(l1), "Leaf(100, 'foo')")
-
- def testLeafStr(self):
- l1 = pytree.Leaf(100, "foo")
- self.assertEqual(str(l1), "foo")
- l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1)))
- self.assertEqual(str(l2), " foo")
-
- def testLeafEq(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0)))
- self.assertEqual(l1, l2)
- l3 = pytree.Leaf(101, "foo")
- l4 = pytree.Leaf(100, "bar")
- self.assertNotEqual(l1, l3)
- self.assertNotEqual(l1, l4)
-
- def testLeafPrefix(self):
- l1 = pytree.Leaf(100, "foo")
- self.assertEqual(l1.get_prefix(), "")
- l1.set_prefix(" ##\n\n")
- self.assertEqual(l1.get_prefix(), " ##\n\n")
-
- def testNode(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(200, "bar")
- n1 = pytree.Node(1000, [l1, l2])
- self.assertEqual(n1.type, 1000)
- self.assertEqual(n1.children, (l1, l2))
-
- def testNodeRepr(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
- n1 = pytree.Node(1000, [l1, l2])
- self.assertEqual(repr(n1),
- "Node(1000, (%s, %s))" % (repr(l1), repr(l2)))
-
- def testNodeStr(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
- n1 = pytree.Node(1000, [l1, l2])
- self.assertEqual(str(n1), "foo bar")
-
- def testNodePrefix(self):
- l1 = pytree.Leaf(100, "foo")
- self.assertEqual(l1.get_prefix(), "")
- n1 = pytree.Node(1000, [l1])
- self.assertEqual(n1.get_prefix(), "")
- n1.set_prefix(" ")
- self.assertEqual(n1.get_prefix(), " ")
- self.assertEqual(l1.get_prefix(), " ")
-
- def testNodeEq(self):
- n1 = pytree.Node(1000, ())
- n2 = pytree.Node(1000, [], context=(" ", (1, 0)))
- self.assertEqual(n1, n2)
- n3 = pytree.Node(1001, ())
- self.assertNotEqual(n1, n3)
-
- def testNodeEqRecursive(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "foo")
- n1 = pytree.Node(1000, [l1])
- n2 = pytree.Node(1000, [l2])
- self.assertEqual(n1, n2)
- l3 = pytree.Leaf(100, "bar")
- n3 = pytree.Node(1000, [l3])
- self.assertNotEqual(n1, n3)
-
- def testReplace(self):
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "+")
- l3 = pytree.Leaf(100, "bar")
- n1 = pytree.Node(1000, [l1, l2, l3])
- self.assertEqual(n1.children, (l1, l2, l3))
- l2new = pytree.Leaf(100, "-")
- l2.replace(l2new)
- self.assertEqual(n1.children, (l1, l2new, l3))
-
- def testConvert(self):
- # XXX
- pass
-
-
-class TestPatterns(unittest.TestCase):
-
- """Unit tests for tree matching patterns."""
-
- def testBasicPatterns(self):
- # Build a tree
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "bar")
- l3 = pytree.Leaf(100, "foo")
- n1 = pytree.Node(1000, [l1, l2])
- n2 = pytree.Node(1000, [l3])
- root = pytree.Node(1000, [n1, n2])
- # Build a pattern matching a leaf
- pl = pytree.LeafPattern(100, "foo", name="pl")
- r = {}
- self.assertEqual(pl.match(root, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pl.match(n1, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pl.match(n2, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pl.match(l1, results=r), True)
- self.assertEqual(r, {"pl": l1})
- r = {}
- self.assertEqual(pl.match(l2, results=r), False)
- self.assertEqual(r, {})
- # Build a pattern matching a node
- pn = pytree.NodePattern(1000, [pl], name="pn")
- self.assertEqual(pn.match(root, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pn.match(n1, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pn.match(n2, results=r), True)
- self.assertEqual(r, {"pn": n2, "pl": l3})
- r = {}
- self.assertEqual(pn.match(l1, results=r), False)
- self.assertEqual(r, {})
- self.assertEqual(pn.match(l2, results=r), False)
- self.assertEqual(r, {})
-
- def testWildcardPatterns(self):
- # Build a tree for testing
- l1 = pytree.Leaf(100, "foo")
- l2 = pytree.Leaf(100, "bar")
- l3 = pytree.Leaf(100, "foo")
- n1 = pytree.Node(1000, [l1, l2])
- n2 = pytree.Node(1000, [l3])
- root = pytree.Node(1000, [n1, n2])
- # Build a pattern
- pl = pytree.LeafPattern(100, "foo", name="pl")
- pn = pytree.NodePattern(1000, [pl], name="pn")
- pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw")
- r = {}
- self.assertEqual(pw.match_seq([root], r), False)
- self.assertEqual(r, {})
- self.assertEqual(pw.match_seq([n1], r), False)
- self.assertEqual(r, {})
- self.assertEqual(pw.match_seq([n2], r), True)
- # These are easier to debug
- self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"])
- self.assertEqual(r["pl"], l1)
- self.assertEqual(r["pn"], n2)
- self.assertEqual(r["pw"], (n2,))
- # But this is equivalent
- self.assertEqual(r, {"pl": l1, "pn": n2, "pw": (n2,)})
- r = {}
- self.assertEqual(pw.match_seq([l1, l3], r), True)
- self.assertEqual(r, {"pl": l3, "pw": (l1, l3)})
- self.assert_(r["pl"] is l3)
- r = {}
-
- def testGenerateMatches(self):
- la = pytree.Leaf(1, "a")
- lb = pytree.Leaf(1, "b")
- lc = pytree.Leaf(1, "c")
- ld = pytree.Leaf(1, "d")
- le = pytree.Leaf(1, "e")
- lf = pytree.Leaf(1, "f")
- leaves = [la, lb, lc, ld, le, lf]
- root = pytree.Node(1000, leaves)
- pa = pytree.LeafPattern(1, "a", "pa")
- pb = pytree.LeafPattern(1, "b", "pb")
- pc = pytree.LeafPattern(1, "c", "pc")
- pd = pytree.LeafPattern(1, "d", "pd")
- pe = pytree.LeafPattern(1, "e", "pe")
- pf = pytree.LeafPattern(1, "f", "pf")
- pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe],
- [pa, pb], [pc, pd], [pe, pf]],
- min=1, max=4, name="pw")
- self.assertEqual([x[0] for x in pw.generate_matches(leaves)],
- [3, 5, 2, 4, 6])
- pr = pytree.NodePattern(type=1000, content=[pw], name="pr")
- matches = list(pytree.generate_matches([pr], [root]))
- self.assertEqual(len(matches), 1)
- c, r = matches[0]
- self.assertEqual(c, 1)
- self.assertEqual(str(r["pr"]), "abcdef")
- self.assertEqual(r["pw"], (la, lb, lc, ld, le, lf))
- for c in "abcdef":
- self.assertEqual(r["p" + c], pytree.Leaf(1, c))
-
- def testHasKeyExample(self):
- pattern = pytree.NodePattern(331,
- (pytree.LeafPattern(7),
- pytree.WildcardPattern(name="args"),
- pytree.LeafPattern(8)))
- l1 = pytree.Leaf(7, "(")
- l2 = pytree.Leaf(3, "x")
- l3 = pytree.Leaf(8, ")")
- node = pytree.Node(331, (l1, l2, l3))
- r = {}
- self.assert_(pattern.match(node, r))
- self.assertEqual(r["args"], (l2,))
-
-
-if __name__ == "__main__":
- import sys
- if not sys.argv[1:]:
- sys.argv.append("-v")
- unittest.main()
Added: sandbox/trunk/2to3/tests/__init__.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/2to3/tests/__init__.py Wed Feb 28 00:45:47 2007
@@ -0,0 +1,23 @@
+"""Make tests/ into a package. This allows us to "import tests" and
+have tests.all_tests be a TestSuite representing all test cases
+from all test_*.py files in tests/."""
+# Author: Collin Winter
+
+import os
+import os.path
+import unittest
+import types
+
+import support
+
+all_tests = unittest.TestSuite()
+
+tests_dir = os.path.join(os.getcwd(), 'tests')
+tests = [t[0:-3] for t in os.listdir(tests_dir)
+ if t.startswith('test_') and t.endswith('.py')]
+
+loader = unittest.TestLoader()
+for t in tests:
+ __import__('tests.' + t)
+ mod = globals()[t]
+ all_tests.addTests(loader.loadTestsFromModule(mod))
Added: sandbox/trunk/2to3/tests/support.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/2to3/tests/support.py Wed Feb 28 00:45:47 2007
@@ -0,0 +1,17 @@
+"""Support code for test_*.py files"""
+# Author: Collin Winter
+
+import unittest
+import sys
+import os.path
+
+def run_all_tests(test_mod=None, tests=None):
+ if tests is None:
+ tests = unittest.TestLoader().loadTestsFromModule(test_mod)
+ unittest.TextTestRunner(verbosity=2).run(tests)
+
+def adjust_path():
+ parent_dir = os.path.split(sys.path[0])[0]
+ sys.path = [parent_dir] + sys.path
+
+TestCase = unittest.TestCase
Copied: sandbox/trunk/2to3/tests/test_fixers.py (from r53996, sandbox/trunk/2to3/fixer_tests.py)
==============================================================================
--- sandbox/trunk/2to3/fixer_tests.py (original)
+++ sandbox/trunk/2to3/tests/test_fixers.py Wed Feb 28 00:45:47 2007
@@ -2,6 +2,11 @@
""" Test suite for the fixer modules """
# Author: Collin Winter
+# Testing imports
+import support
+if __name__ == '__main__':
+ support.adjust_path()
+
# Python imports
from StringIO import StringIO
import re
@@ -45,7 +50,7 @@
self.verbose = False
-class FixerTestCase(unittest.TestCase):
+class FixerTestCase(support.TestCase):
def setUp(self):
options = Options(fix=[self.fixer], print_function=False)
self.refactor = refactor.RefactoringTool(options)
@@ -1120,7 +1125,5 @@
if __name__ == "__main__":
- import sys
- if not sys.argv[1:]:
- sys.argv.append("-v")
- unittest.main()
+ import __main__
+ support.run_all_tests(__main__)
Copied: sandbox/trunk/2to3/tests/test_pytree.py (from r53996, sandbox/trunk/2to3/tests.py)
==============================================================================
--- sandbox/trunk/2to3/tests.py (original)
+++ sandbox/trunk/2to3/tests/test_pytree.py Wed Feb 28 00:45:47 2007
@@ -10,14 +10,16 @@
especially when debugging a test.
"""
-# Python imports
-import unittest
+# Testing imports
+import support
+if __name__ == '__main__':
+ support.adjust_path()
# Local imports (XXX should become a package)
import pytree
-class TestNodes(unittest.TestCase):
+class TestNodes(support.TestCase):
"""Unit tests for nodes (Base, Leaf, Node)."""
@@ -117,7 +119,7 @@
pass
-class TestPatterns(unittest.TestCase):
+class TestPatterns(support.TestCase):
"""Unit tests for tree matching patterns."""
@@ -233,7 +235,5 @@
if __name__ == "__main__":
- import sys
- if not sys.argv[1:]:
- sys.argv.append("-v")
- unittest.main()
+ import __main__
+ support.run_all_tests(__main__)
1
0
Author: collin.winter
Date: Wed Feb 28 00:06:37 2007
New Revision: 54006
Modified:
sandbox/trunk/2to3/README
Log:
Update to reflect that tokenize.py now lives in pgen2/
Modified: sandbox/trunk/2to3/README
==============================================================================
--- sandbox/trunk/2to3/README (original)
+++ sandbox/trunk/2to3/README Wed Feb 28 00:06:37 2007
@@ -10,19 +10,20 @@
patcomp.py - pattern compiler
pytree.py - parse tree nodes (not specific to Python, despite the name!)
pygram.py - code specific to the Python grammar
-tokenize.py - modified version of stdlib tokenize.py (1)
example.py - example input for play.py and fix_*.py
Grammar.txt - Python grammar input (a copy of Python 2.5's Grammar/Grammar)
Grammar.pickle - pickled grammar tables (generated file, not in subversion)
PatternGrammar.txt - grammar for the pattern language used by patcomp.py
PatternGrammar.pickle - pickled pattern grammar tables (generated file)
-pgen2/ - Parser generator and driver (2)
+pgen2/ - Parser generator and driver (1) (2)
fixes/ - Individual transformations
+
Notes:
(1) I modified tokenize.py to yield a NL pseudo-token for backslash
continuations, so the original source can be reproduced exactly.
+ The modified version can be found at pgen2/tokenize.py.
(2) I developed pgen2 while I was at Elemental Security. I modified
it while at Google to suit the needs of this refactoring tool.
1
0

r54005 - sandbox/trunk/2to3/fixes/fix_apply.py sandbox/trunk/2to3/fixes/fix_except.py sandbox/trunk/2to3/fixes/fix_exec.py sandbox/trunk/2to3/fixes/fix_has_key.py sandbox/trunk/2to3/fixes/fix_intern.py sandbox/trunk/2to3/fixes/fix_raise.py sandbox/trunk/2to3/fixes/fix_throw.py
by collin.winter Feb. 27, 2007
by collin.winter Feb. 27, 2007
Feb. 27, 2007
Author: collin.winter
Date: Wed Feb 28 00:02:12 2007
New Revision: 54005
Modified:
sandbox/trunk/2to3/fixes/fix_apply.py
sandbox/trunk/2to3/fixes/fix_except.py
sandbox/trunk/2to3/fixes/fix_exec.py
sandbox/trunk/2to3/fixes/fix_has_key.py
sandbox/trunk/2to3/fixes/fix_intern.py
sandbox/trunk/2to3/fixes/fix_raise.py
sandbox/trunk/2to3/fixes/fix_throw.py
Log:
More comprehensive docstrings for fixer modules
Modified: sandbox/trunk/2to3/fixes/fix_apply.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_apply.py (original)
+++ sandbox/trunk/2to3/fixes/fix_apply.py Wed Feb 28 00:02:12 2007
@@ -1,7 +1,9 @@
# Copyright 2006 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.
-"""Fixer for apply()."""
+"""Fixer for apply().
+
+This converts apply(func, v, k) into (func)(*v, **k)."""
# Local imports
import pytree
Modified: sandbox/trunk/2to3/fixes/fix_except.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_except.py (original)
+++ sandbox/trunk/2to3/fixes/fix_except.py Wed Feb 28 00:02:12 2007
@@ -1,4 +1,26 @@
-"""Fixer for except statements with named exceptions."""
+"""Fixer for except statements with named exceptions.
+
+The following cases will be converted:
+
+- "except E, T:" where T is a name:
+
+ except E as T:
+
+- "except E, T:" where T is not a name, tuple or list:
+
+ except E as t:
+ T = t
+
+ This is done because the target of an "except" clause must be a
+ name.
+
+- "except E, T:" where T is a tuple or list literal:
+
+ except E as t:
+ T = t.message
+
+ This transformation is still under consideration.
+"""
# Author: Collin Winter
# Local imports
@@ -18,8 +40,6 @@
as_leaf = pytree.Leaf(token.NAME, "as")
as_leaf.set_prefix(" ")
-tuple_reason = "exception unpacking is going away"
-
class FixExcept(basefix.BaseFix):
PATTERN = """
Modified: sandbox/trunk/2to3/fixes/fix_exec.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_exec.py (original)
+++ sandbox/trunk/2to3/fixes/fix_exec.py Wed Feb 28 00:02:12 2007
@@ -1,7 +1,13 @@
# Copyright 2006 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.
-"""Fixer for exec."""
+"""Fixer for exec.
+
+This converts usages of the exec statement into calls to a built-in
+exec() function.
+
+exec code in ns1, ns2 -> exec(code, ns1, ns2)
+"""
# Local imports
import pytree
Modified: sandbox/trunk/2to3/fixes/fix_has_key.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_has_key.py (original)
+++ sandbox/trunk/2to3/fixes/fix_has_key.py Wed Feb 28 00:02:12 2007
@@ -1,7 +1,33 @@
# Copyright 2006 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.
-"""Fixer for has_key()."""
+"""Fixer for has_key().
+
+Calls to .has_key() methods are expressed in terms of the 'in'
+operator:
+
+ d.has_key(k) -> k in d
+
+CAVEATS:
+1) While the primary target of this fixer is dict.has_key(), the
+ fixer will change any has_key() method call, regardless of its
+ class.
+
+2) Cases like this will not be converted:
+
+ m = d.has_key
+ if m(k):
+ ...
+
+ Only *calls* to has_key() are converted. While it is possible to
+ convert the above to something like
+
+ m = d.__contains__
+ if m(k):
+ ...
+
+ this is currently not done.
+"""
# Local imports
import pytree
Modified: sandbox/trunk/2to3/fixes/fix_intern.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_intern.py (original)
+++ sandbox/trunk/2to3/fixes/fix_intern.py Wed Feb 28 00:02:12 2007
@@ -1,7 +1,9 @@
# Copyright 2006 Georg Brandl.
# Licensed to PSF under a Contributor Agreement.
-"""Fixer for intern()."""
+"""Fixer for intern().
+
+intern(s) -> sys.intern(s)"""
# Local imports
import pytree
Modified: sandbox/trunk/2to3/fixes/fix_raise.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_raise.py (original)
+++ sandbox/trunk/2to3/fixes/fix_raise.py Wed Feb 28 00:02:12 2007
@@ -1,4 +1,24 @@
-"""Fixer for 'raise E, V, T'"""
+"""Fixer for 'raise E, V, T'
+
+raise -> raise
+raise E -> raise E
+raise E, V -> raise E(V)
+raise E, V, T -> raise E(V).with_traceback(T)
+
+raise (((E, E'), E''), E'''), V -> raise E(V)
+raise "foo", V, T -> warns about string exceptions
+
+
+CAVEATS:
+1) "raise E, V" will be incorrectly translated if V is an exception
+ instance. The correct Python 3 idiom is
+
+ raise E from V
+
+ but since we can't detect instance-hood by syntax alone and since
+ any client code would have to be changed as well, we don't automate
+ this.
+"""
# Author: Collin Winter
# Local imports
Modified: sandbox/trunk/2to3/fixes/fix_throw.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_throw.py (original)
+++ sandbox/trunk/2to3/fixes/fix_throw.py Wed Feb 28 00:02:12 2007
@@ -1,4 +1,10 @@
-"""Fixer for generator.throw(E, V, T)"""
+"""Fixer for generator.throw(E, V, T).
+
+g.throw(E) -> g.throw(E)
+g.throw(E, V) -> g.throw(E(V))
+g.throw(E, V, T) -> g.throw(E(V).with_traceback(T))
+
+g.throw("foo"[, V[, T]]) will warn about string exceptions."""
# Author: Collin Winter
# Local imports
1
0
Author: jeremy.hylton
Date: Tue Feb 27 19:33:31 2007
New Revision: 53998
Modified:
python/trunk/Misc/NEWS
Log:
Add news about changes to metaclasses and __bases__ error checking.
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Tue Feb 27 19:33:31 2007
@@ -126,6 +126,13 @@
- Bug #1664966: Fix crash in exec if Unicode filename can't be decoded.
+- Add new requirements for metaclasses. 1) If type or a subclass of type
+ occurs in __bases__, it must occur before any non-type bases, e.g.
+ before regular classes. 2) If you assign to __bases__, you may not
+ change the metaclass. Many more illegal assignments to __bases__
+ are now checked and raise TypeErrors. This changed fixed at least
+ one known crash.
+
Library
-------
1
0

r53997 - in python/trunk: Lib/test/crashers/modify_dict_attr.py Lib/test/test_descr.py Objects/typeobject.c
by jeremy.hylton Feb. 27, 2007
by jeremy.hylton Feb. 27, 2007
Feb. 27, 2007
Author: jeremy.hylton
Date: Tue Feb 27 19:29:45 2007
New Revision: 53997
Removed:
python/trunk/Lib/test/crashers/modify_dict_attr.py
Modified:
python/trunk/Lib/test/test_descr.py
python/trunk/Objects/typeobject.c
Log:
Add checking for a number of metaclass error conditions.
We add some new rules that are required for preserving internal
invariants of types.
1. If type (or a subclass of type) appears in bases, it must appear
before any non-type bases. If a non-type base (like a regular
new-style class) occurred first, it could trick type into
allocating the new class an __dict__ which must be impossible.
2. There are several checks that are made of bases when creating a
type. Those checks are now repeated when assigning to __bases__.
We also add the restriction that assignment to __bases__ may not
change the metaclass of the type.
Add new tests for these cases and for a few other oddball errors that
were no previously tested. Remove a crasher test that was fixed.
Also some internal refactoring: Extract the code to find the most
derived metaclass of a type and its bases. It is now needed in two
places. Rewrite the TypeError checks in test_descr to use doctest.
The tests now clearly show what exception they expect to see.
Deleted: /python/trunk/Lib/test/crashers/modify_dict_attr.py
==============================================================================
--- /python/trunk/Lib/test/crashers/modify_dict_attr.py Tue Feb 27 19:29:45 2007
+++ (empty file)
@@ -1,19 +0,0 @@
-
-# http://python.org/sf/1303614
-
-class Y(object):
- pass
-
-class type_with_modifiable_dict(Y, type):
- pass
-
-class MyClass(object):
- """This class has its __dict__ attribute completely exposed:
- user code can read, reassign and even delete it.
- """
- __metaclass__ = type_with_modifiable_dict
-
-
-if __name__ == '__main__':
- del MyClass.__dict__ # if we set tp_dict to NULL,
- print MyClass # doing anything with MyClass segfaults
Modified: python/trunk/Lib/test/test_descr.py
==============================================================================
--- python/trunk/Lib/test/test_descr.py (original)
+++ python/trunk/Lib/test/test_descr.py Tue Feb 27 19:29:45 2007
@@ -1,6 +1,6 @@
# Test enhancements related to descriptors and new-style classes
-from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout
+from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout, run_doctest
from copy import deepcopy
import warnings
@@ -820,6 +820,22 @@
except TypeError: pass
else: raise TestFailed, "calling object w/o call method should raise TypeError"
+ # Testing code to find most derived baseclass
+ class A(type):
+ def __new__(*args, **kwargs):
+ return type.__new__(*args, **kwargs)
+
+ class B(object):
+ pass
+
+ class C(object):
+ __metaclass__ = A
+
+ # The most derived metaclass of D is A rather than type.
+ class D(B, C):
+ pass
+
+
def pymods():
if verbose: print "Testing Python subclass of module..."
log = []
@@ -1411,49 +1427,89 @@
verify(someclass != object)
def errors():
- if verbose: print "Testing errors..."
-
- try:
- class C(list, dict):
- pass
- except TypeError:
- pass
- else:
- verify(0, "inheritance from both list and dict should be illegal")
-
- try:
- class C(object, None):
- pass
- except TypeError:
- pass
- else:
- verify(0, "inheritance from non-type should be illegal")
- class Classic:
- pass
+ """Test that type can't be placed after an instance of type in bases.
- try:
- class C(type(len)):
- pass
- except TypeError:
- pass
- else:
- verify(0, "inheritance from CFunction should be illegal")
-
- try:
- class C(object):
- __slots__ = 1
- except TypeError:
- pass
- else:
- verify(0, "__slots__ = 1 should be illegal")
-
- try:
- class C(object):
- __slots__ = [1]
- except TypeError:
- pass
- else:
- verify(0, "__slots__ = [1] should be illegal")
+ >>> class C(list, dict):
+ ... pass
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ multiple bases have instance lay-out conflict
+
+ >>> class C(object, None):
+ ... pass
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ bases must be types
+
+ >>> class C(type(len)):
+ ... pass
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ type 'builtin_function_or_method' is not an acceptable base type
+
+ >>> class Classic:
+ ... def __init__(*args): pass
+ >>> class C(object):
+ ... __metaclass__ = Classic
+
+ >>> class C(object):
+ ... __slots__ = 1
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ 'int' object is not iterable
+
+ >>> class C(object):
+ ... __slots__ = [1]
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ __slots__ items must be strings, not 'int'
+
+ >>> class A(object):
+ ... pass
+
+ >>> class B(A, type):
+ ... pass
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ metaclass conflict: type must occur in bases before other non-classic base classes
+
+ Create two different metaclasses in order to setup an error where
+ there is no inheritance relationship between the metaclass of a class
+ and the metaclass of its bases.
+
+ >>> class M1(type):
+ ... pass
+ >>> class M2(type):
+ ... pass
+ >>> class A1(object):
+ ... __metaclass__ = M1
+ >>> class A2(object):
+ ... __metaclass__ = M2
+ >>> class B(A1, A2):
+ ... pass
+ Traceback (most recent call last):
+ TypeError: Error when calling the metaclass bases
+ metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+ >>> class B(A1):
+ ... pass
+
+ Also check that assignment to bases is safe.
+
+ >>> B.__bases__ = A1, A2
+ Traceback (most recent call last):
+ TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+ >>> B.__bases__ = A2,
+ Traceback (most recent call last):
+ TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+
+ >>> class M3(M1):
+ ... pass
+ >>> class C(object):
+ ... __metaclass__ = M3
+ >>> B.__bases__ = C,
+ Traceback (most recent call last):
+ TypeError: assignment to __bases__ may not change metatype
+ """
def classmethods():
if verbose: print "Testing class methods..."
@@ -4179,7 +4235,6 @@
slots()
slotspecials()
dynamics()
- errors()
classmethods()
classmethods_in_c()
staticmethods()
@@ -4247,6 +4302,9 @@
methodwrapper()
notimplemented()
+ from test import test_descr
+ run_doctest(test_descr, verbosity=True)
+
if verbose: print "All OK"
if __name__ == "__main__":
Modified: python/trunk/Objects/typeobject.c
==============================================================================
--- python/trunk/Objects/typeobject.c (original)
+++ python/trunk/Objects/typeobject.c Tue Feb 27 19:29:45 2007
@@ -127,6 +127,7 @@
return type->tp_bases;
}
+static PyTypeObject *most_derived_metaclass(PyTypeObject *, PyObject *);
static PyTypeObject *best_base(PyObject *);
static int mro_internal(PyTypeObject *);
static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *);
@@ -187,7 +188,7 @@
Py_ssize_t i;
int r = 0;
PyObject *ob, *temp;
- PyTypeObject *new_base, *old_base;
+ PyTypeObject *new_base, *old_base, *metatype;
PyObject *old_bases, *old_mro;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
@@ -230,6 +231,17 @@
}
}
+
+ metatype = most_derived_metaclass(type->ob_type, value);
+ if (metatype == NULL)
+ return -1;
+ if (metatype != type->ob_type) {
+ PyErr_SetString(PyExc_TypeError,
+ "assignment to __bases__ may not change "
+ "metatype");
+ return -1;
+ }
+
new_base = best_base(value);
if (!new_base) {
@@ -1355,7 +1367,14 @@
/* Calculate the best base amongst multiple base classes.
- This is the first one that's on the path to the "solid base". */
+ This is the first one that's on the path to the "solid base".
+
+ Requires that all base classes be types or classic classes.
+
+ Will return NULL with TypeError set if
+ 1) the base classes have conflicting layout instances, or
+ 2) all the bases are classic classes.
+*/
static PyTypeObject *
best_base(PyObject *bases)
@@ -1373,12 +1392,7 @@
base_proto = PyTuple_GET_ITEM(bases, i);
if (PyClass_Check(base_proto))
continue;
- if (!PyType_Check(base_proto)) {
- PyErr_SetString(
- PyExc_TypeError,
- "bases must be types");
- return NULL;
- }
+ assert(PyType_Check(base_proto));
base_i = (PyTypeObject *)base_proto;
if (base_i->tp_dict == NULL) {
if (PyType_Ready(base_i) < 0)
@@ -1431,6 +1445,8 @@
return t_size != b_size;
}
+/* Return the type object that will determine the layout of the instance. */
+
static PyTypeObject *
solid_base(PyTypeObject *type)
{
@@ -1446,6 +1462,71 @@
return base;
}
+/* Determine the proper metatype to deal with this, and check some
+ error cases while we're at it. Note that if some other metatype
+ wins to contract, it's possible that its instances are not types.
+
+ Error cases of interest: 1. The metaclass is not a subclass of a
+ base class. 2. A non-type, non-classic base class appears before
+ type.
+*/
+
+static PyTypeObject *
+most_derived_metaclass(PyTypeObject *metatype, PyObject *bases)
+{
+ Py_ssize_t nbases, i;
+ PyTypeObject *winner;
+ /* types_ordered: One of three states possible:
+ 0 type is in bases
+ 1 non-types also in bases
+ 2 type follows non-type in bases (error)
+ */
+ int types_ordered = 0;
+
+ nbases = PyTuple_GET_SIZE(bases);
+ winner = metatype;
+ for (i = 0; i < nbases; i++) {
+ PyObject *tmp = PyTuple_GET_ITEM(bases, i);
+ PyTypeObject *tmptype = tmp->ob_type;
+ if (tmptype == &PyClass_Type)
+ continue; /* Special case classic classes */
+ if (!PyType_Check(tmp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "bases must be types");
+ return NULL;
+ }
+ if (PyObject_IsSubclass(tmp, (PyObject*)&PyType_Type)) {
+ if (types_ordered == 1) {
+ types_ordered = 2;
+ }
+ }
+ else if (!types_ordered)
+ types_ordered = 1;
+ if (winner == tmptype)
+ continue;
+ if (PyType_IsSubtype(winner, tmptype))
+ continue;
+ if (PyType_IsSubtype(tmptype, winner)) {
+ winner = tmptype;
+ continue;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases");
+ return NULL;
+ }
+ if (types_ordered == 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "type must occur in bases before other "
+ "non-classic base classes");
+ return NULL;
+ }
+ return winner;
+}
+
static void object_dealloc(PyObject *);
static int object_init(PyObject *, PyObject *, PyObject *);
static int update_slot(PyTypeObject *, PyObject *);
@@ -1642,37 +1723,18 @@
&PyDict_Type, &dict))
return NULL;
- /* Determine the proper metatype to deal with this,
- and check for metatype conflicts while we're at it.
- Note that if some other metatype wins to contract,
- it's possible that its instances are not types. */
- nbases = PyTuple_GET_SIZE(bases);
- winner = metatype;
- for (i = 0; i < nbases; i++) {
- tmp = PyTuple_GET_ITEM(bases, i);
- tmptype = tmp->ob_type;
- if (tmptype == &PyClass_Type)
- continue; /* Special case classic classes */
- if (PyType_IsSubtype(winner, tmptype))
- continue;
- if (PyType_IsSubtype(tmptype, winner)) {
- winner = tmptype;
- continue;
- }
- PyErr_SetString(PyExc_TypeError,
- "metaclass conflict: "
- "the metaclass of a derived class "
- "must be a (non-strict) subclass "
- "of the metaclasses of all its bases");
+ winner = most_derived_metaclass(metatype, bases);
+ if (winner == NULL)
return NULL;
- }
if (winner != metatype) {
- if (winner->tp_new != type_new) /* Pass it to the winner */
+ if (winner->tp_new != type_new) /* Pass it to the winner */ {
return winner->tp_new(winner, args, kwds);
+ }
metatype = winner;
}
/* Adjust for empty tuple bases */
+ nbases = PyTuple_GET_SIZE(bases);
if (nbases == 0) {
bases = PyTuple_Pack(1, &PyBaseObject_Type);
if (bases == NULL)
1
0
Author: jeremy.hylton
Date: Tue Feb 27 18:24:48 2007
New Revision: 53996
Modified:
python/trunk/Objects/typeobject.c
Log:
whitespace normalization
Modified: python/trunk/Objects/typeobject.c
==============================================================================
--- python/trunk/Objects/typeobject.c (original)
+++ python/trunk/Objects/typeobject.c Tue Feb 27 18:24:48 2007
@@ -531,7 +531,7 @@
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
/* For a heaptype, the instances count as references
- to the type. Traverse the type so the collector
+ to the type. Traverse the type so the collector
can find cycles involving this link. */
Py_VISIT(type);
@@ -651,7 +651,7 @@
assert(base);
}
- /* If we added a weaklist, we clear it. Do this *before* calling
+ /* If we added a weaklist, we clear it. Do this *before* calling
the finalizer (__del__), clearing slots, or clearing the instance
dict. */
@@ -722,7 +722,7 @@
A. Read the comment titled "Trashcan mechanism" in object.h.
For one, this explains why there must be a call to GC-untrack
- before the trashcan begin macro. Without understanding the
+ before the trashcan begin macro. Without understanding the
trashcan code, the answers to the following questions don't make
sense.
@@ -730,7 +730,7 @@
GC-track again afterward?
A. In the case that the base class is GC-aware, the base class
- probably GC-untracks the object. If it does that using the
+ probably GC-untracks the object. If it does that using the
UNTRACK macro, this will crash when the object is already
untracked. Because we don't know what the base class does, the
only safe thing is to make sure the object is tracked when we
@@ -738,19 +738,19 @@
requires that the object is *untracked* before it is called. So
the dance becomes:
- GC untrack
+ GC untrack
trashcan begin
GC track
- Q. Why did the last question say "immediately GC-track again"?
- It's nowhere near immediately.
+ Q. Why did the last question say "immediately GC-track again"?
+ It's nowhere near immediately.
- A. Because the code *used* to re-track immediately. Bad Idea.
- self has a refcount of 0, and if gc ever gets its hands on it
- (which can happen if any weakref callback gets invoked), it
- looks like trash to gc too, and gc also tries to delete self
- then. But we're already deleting self. Double dealloction is
- a subtle disaster.
+ A. Because the code *used* to re-track immediately. Bad Idea.
+ self has a refcount of 0, and if gc ever gets its hands on it
+ (which can happen if any weakref callback gets invoked), it
+ looks like trash to gc too, and gc also tries to delete self
+ then. But we're already deleting self. Double dealloction is
+ a subtle disaster.
Q. Why the bizarre (net-zero) manipulation of
_PyTrash_delete_nesting around the trashcan macros?
@@ -763,17 +763,17 @@
- subtype_dealloc() is called
- the trashcan limit is not yet reached, so the trashcan level
- is incremented and the code between trashcan begin and end is
- executed
+ is incremented and the code between trashcan begin and end is
+ executed
- this destroys much of the object's contents, including its
- slots and __dict__
+ slots and __dict__
- basedealloc() is called; this is really list_dealloc(), or
- some other type which also uses the trashcan macros
+ some other type which also uses the trashcan macros
- the trashcan limit is now reached, so the object is put on the
- trashcan's to-be-deleted-later list
+ trashcan's to-be-deleted-later list
- basedealloc() returns
@@ -782,13 +782,13 @@
- subtype_dealloc() returns
- later, the trashcan code starts deleting the objects from its
- to-be-deleted-later list
+ to-be-deleted-later list
- subtype_dealloc() is called *AGAIN* for the same object
- at the very least (if the destroyed slots and __dict__ don't
- cause problems) the object's type gets decref'ed a second
- time, which is *BAD*!!!
+ cause problems) the object's type gets decref'ed a second
+ time, which is *BAD*!!!
The remedy is to make sure that if the code between trashcan
begin and end in subtype_dealloc() is called, the code between
@@ -800,7 +800,7 @@
But now it's possible that a chain of objects consisting solely
of objects whose deallocator is subtype_dealloc() will defeat
the trashcan mechanism completely: the decremented level means
- that the effective level never reaches the limit. Therefore, we
+ that the effective level never reaches the limit. Therefore, we
*increment* the level *before* entering the trashcan block, and
matchingly decrement it after leaving. This means the trashcan
code will trigger a little early, but that's no big deal.
@@ -854,7 +854,7 @@
/* Internal routines to do a method lookup in the type
without looking in the instance dictionary
(so we can't use PyObject_GetAttr) but still binding
- it to the instance. The arguments are the object,
+ it to the instance. The arguments are the object,
the method name as a C string, and the address of a
static variable used to cache the interned Python string.
@@ -897,7 +897,7 @@
}
/* A variation of PyObject_CallMethod that uses lookup_method()
- instead of PyObject_GetAttrString(). This uses the same convention
+ instead of PyObject_GetAttrString(). This uses the same convention
as lookup_method to cache the interned name string object. */
static PyObject *
@@ -1099,7 +1099,7 @@
It's hard to produce a good error message. In the absence of better
insight into error reporting, report the classes that were candidates
- to be put next into the MRO. There is some conflict between the
+ to be put next into the MRO. There is some conflict between the
order in which they should be put in the MRO, but it's hard to
diagnose what constraint can't be satisfied.
*/
@@ -1171,7 +1171,7 @@
if (remain[i] >= PyList_GET_SIZE(cur_list)) {
empty_cnt++;
continue;
- }
+ }
/* Choose next candidate for MRO.
@@ -1252,7 +1252,7 @@
if (parentMRO == NULL) {
Py_DECREF(to_merge);
return NULL;
- }
+ }
PyList_SET_ITEM(to_merge, i, parentMRO);
}
@@ -1790,8 +1790,8 @@
(add_weak && strcmp(s, "__weakref__") == 0))
continue;
tmp =_Py_Mangle(name, tmp);
- if (!tmp)
- goto bad_slots;
+ if (!tmp)
+ goto bad_slots;
PyTuple_SET_ITEM(newslots, j, tmp);
j++;
}
@@ -1903,13 +1903,13 @@
PyObject *doc = PyDict_GetItemString(dict, "__doc__");
if (doc != NULL && PyString_Check(doc)) {
const size_t n = (size_t)PyString_GET_SIZE(doc);
- char *tp_doc = (char *)PyObject_MALLOC(n+1);
+ char *tp_doc = (char *)PyObject_MALLOC(n+1);
if (tp_doc == NULL) {
Py_DECREF(type);
return NULL;
}
memcpy(tp_doc, PyString_AS_STRING(doc), n+1);
- type->tp_doc = tp_doc;
+ type->tp_doc = tp_doc;
}
}
@@ -2153,9 +2153,9 @@
Py_XDECREF(type->tp_mro);
Py_XDECREF(type->tp_cache);
Py_XDECREF(type->tp_subclasses);
- /* A type's tp_doc is heap allocated, unlike the tp_doc slots
- * of most other objects. It's okay to cast it to char *.
- */
+ /* A type's tp_doc is heap allocated, unlike the tp_doc slots
+ * of most other objects. It's okay to cast it to char *.
+ */
PyObject_Free((char *)type->tp_doc);
Py_XDECREF(et->ht_name);
Py_XDECREF(et->ht_slots);
@@ -2274,7 +2274,7 @@
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
- 0, /* tp_getattr */
+ 0, /* tp_getattr */
0, /* tp_setattr */
type_compare, /* tp_compare */
(reprfunc)type_repr, /* tp_repr */
@@ -2307,7 +2307,7 @@
0, /* tp_init */
0, /* tp_alloc */
type_new, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+ PyObject_GC_Del, /* tp_free */
(inquiry)type_is_gc, /* tp_is_gc */
};
@@ -2770,13 +2770,13 @@
PyTypeObject PyBaseObject_Type = {
PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
+ 0, /* ob_size */
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
object_dealloc, /* tp_dealloc */
0, /* tp_print */
- 0, /* tp_getattr */
+ 0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
object_repr, /* tp_repr */
@@ -2808,7 +2808,7 @@
object_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
object_new, /* tp_new */
- PyObject_Del, /* tp_free */
+ PyObject_Del, /* tp_free */
};
@@ -3195,9 +3195,9 @@
Py_INCREF(base);
}
- /* Now the only way base can still be NULL is if type is
- * &PyBaseObject_Type.
- */
+ /* Now the only way base can still be NULL is if type is
+ * &PyBaseObject_Type.
+ */
/* Initialize the base class */
if (base && base->tp_dict == NULL) {
@@ -3205,13 +3205,13 @@
goto error;
}
- /* Initialize ob_type if NULL. This means extensions that want to be
+ /* Initialize ob_type if NULL. This means extensions that want to be
compilable separately on Windows can call PyType_Ready() instead of
initializing the ob_type field of their type objects. */
- /* The test for base != NULL is really unnecessary, since base is only
- NULL when type is &PyBaseObject_Type, and we know its ob_type is
- not NULL (it's initialized to &PyType_Type). But coverity doesn't
- know that. */
+ /* The test for base != NULL is really unnecessary, since base is only
+ NULL when type is &PyBaseObject_Type, and we know its ob_type is
+ not NULL (it's initialized to &PyType_Type). But coverity doesn't
+ know that. */
if (type->ob_type == NULL && base != NULL)
type->ob_type = base->ob_type;
@@ -3275,9 +3275,9 @@
/* Sanity check for tp_free. */
if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&
(type->tp_free == NULL || type->tp_free == PyObject_Del)) {
- /* This base class needs to call tp_free, but doesn't have
- * one, or its tp_free is for non-gc'ed objects.
- */
+ /* This base class needs to call tp_free, but doesn't have
+ * one, or its tp_free is for non-gc'ed objects.
+ */
PyErr_Format(PyExc_TypeError, "type '%.100s' participates in "
"gc and is a base type but has inappropriate "
"tp_free slot",
@@ -3404,7 +3404,7 @@
/* Generic wrappers for overloadable 'operators' such as __getitem__ */
/* There's a wrapper *function* for each distinct function typedef used
- for type object slots (e.g. binaryfunc, ternaryfunc, etc.). There's a
+ for type object slots (e.g. binaryfunc, ternaryfunc, etc.). There's a
wrapper *table* for each distinct operation (e.g. __len__, __add__).
Most tables have only one entry; the tables for binary operators have two
entries, one regular and one with reversed arguments. */
@@ -3773,8 +3773,8 @@
PyTypeObject *type = self->ob_type;
while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
type = type->tp_base;
- /* If type is NULL now, this is a really weird type.
- In the spirit of backwards compatibility (?), just shut up. */
+ /* If type is NULL now, this is a really weird type.
+ In the spirit of backwards compatibility (?), just shut up. */
if (type && type->tp_setattro != func) {
PyErr_Format(PyExc_TypeError,
"can't apply this %s to %s object",
@@ -3990,8 +3990,8 @@
staticbase = subtype;
while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))
staticbase = staticbase->tp_base;
- /* If staticbase is NULL now, it is a really weird type.
- In the spirit of backwards compatibility (?), just shut up. */
+ /* If staticbase is NULL now, it is a really weird type.
+ In the spirit of backwards compatibility (?), just shut up. */
if (staticbase && staticbase->tp_new != type->tp_new) {
PyErr_Format(PyExc_TypeError,
"%s.__new__(%s) is not safe, use %s.__new__()",
@@ -4012,7 +4012,7 @@
static struct PyMethodDef tp_new_methoddef[] = {
{"__new__", (PyCFunction)tp_new_wrapper, METH_KEYWORDS,
PyDoc_STR("T.__new__(S, ...) -> "
- "a new object with type S, a subtype of T")},
+ "a new object with type S, a subtype of T")},
{0}
};
@@ -4341,7 +4341,7 @@
func = lookup_maybe(self, "__len__", &len_str);
if (func == NULL)
return PyErr_Occurred() ? -1 : 1;
- }
+ }
args = PyTuple_New(0);
if (args != NULL) {
PyObject *temp = PyObject_Call(func, args, NULL);
@@ -5020,17 +5020,17 @@
user-defined methods has unexpected side-effects, as shown by
test_descr.notimplemented() */
SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
- "x.__add__(y) <==> x+y"),
+ "x.__add__(y) <==> x+y"),
SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
- "x.__mul__(n) <==> x*n"),
+ "x.__mul__(n) <==> x*n"),
SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
- "x.__rmul__(n) <==> n*x"),
+ "x.__rmul__(n) <==> n*x"),
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
"x.__getitem__(y) <==> x[y]"),
SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
"x.__getslice__(i, j) <==> x[i:j]\n\
- \n\
- Use of negative indices is not supported."),
+ \n\
+ Use of negative indices is not supported."),
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
"x.__setitem__(i, y) <==> x[i]=y"),
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
@@ -5038,18 +5038,18 @@
SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
wrap_ssizessizeobjargproc,
"x.__setslice__(i, j, y) <==> x[i:j]=y\n\
- \n\
- Use of negative indices is not supported."),
+ \n\
+ Use of negative indices is not supported."),
SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
"x.__delslice__(i, j) <==> del x[i:j]\n\
- \n\
- Use of negative indices is not supported."),
+ \n\
+ Use of negative indices is not supported."),
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
"x.__contains__(y) <==> y in x"),
SQSLOT("__iadd__", sq_inplace_concat, NULL,
- wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+ wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
SQSLOT("__imul__", sq_inplace_repeat, NULL,
- wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+ wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
"x.__len__() <==> len(x)"),
@@ -5208,7 +5208,7 @@
};
/* Given a type pointer and an offset gotten from a slotdef entry, return a
- pointer to the actual slot. This is not quite the same as simply adding
+ pointer to the actual slot. This is not quite the same as simply adding
the offset to the type pointer, since it takes care to indirect through the
proper indirection pointer (as_buffer, etc.); it returns NULL if the
indirection pointer is NULL. */
@@ -5272,7 +5272,7 @@
}
/* Look in all matching slots of the type; if exactly one of these has
- a filled-in slot, return its value. Otherwise return NULL. */
+ a filled-in slot, return its value. Otherwise return NULL. */
res = NULL;
for (pp = ptrs; *pp; pp++) {
ptr = slotptr(type, (*pp)->offset);
@@ -5511,13 +5511,13 @@
dictionary with method descriptors for function slots. For each
function slot (like tp_repr) that's defined in the type, one or more
corresponding descriptors are added in the type's tp_dict dictionary
- under the appropriate name (like __repr__). Some function slots
+ under the appropriate name (like __repr__). Some function slots
cause more than one descriptor to be added (for example, the nb_add
slot adds both __add__ and __radd__ descriptors) and some function
slots compete for the same descriptor (for example both sq_item and
mp_subscript generate a __getitem__ descriptor).
- In the latter case, the first slotdef entry encoutered wins. Since
+ In the latter case, the first slotdef entry encoutered wins. Since
slotdef entries are sorted by the offset of the slot in the
PyHeapTypeObject, this gives us some control over disambiguating
between competing slots: the members of PyHeapTypeObject are listed
@@ -5691,7 +5691,7 @@
obj can be a new-style class, or an instance of one:
- - If it is a class, it must be a subclass of 'type'. This case is
+ - If it is a class, it must be a subclass of 'type'. This case is
used for class methods; the return value is obj.
- If it is an instance, it must be an instance of 'type'. This is
@@ -5742,7 +5742,7 @@
Py_DECREF(class_attr);
}
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_TypeError,
"super(type, obj): "
"obj must be an instance or subtype of type");
return NULL;
@@ -5763,7 +5763,7 @@
/* If su is an instance of a (strict) subclass of super,
call its type */
return PyObject_CallFunctionObjArgs((PyObject *)su->ob_type,
- su->type, obj, NULL);
+ su->type, obj, NULL);
else {
/* Inline the common case */
PyTypeObject *obj_type = supercheck(su->type, obj);
@@ -5816,7 +5816,7 @@
"Typical use to call a cooperative superclass method:\n"
"class C(B):\n"
" def meth(self, arg):\n"
-" super(C, self).meth(arg)");
+" super(C, self).meth(arg)");
static int
super_traverse(PyObject *self, visitproc visit, void *arg)
@@ -5837,7 +5837,7 @@
sizeof(superobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- super_dealloc, /* tp_dealloc */
+ super_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -5845,7 +5845,7 @@
super_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
+ 0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
@@ -5854,9 +5854,9 @@
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- super_doc, /* tp_doc */
- super_traverse, /* tp_traverse */
- 0, /* tp_clear */
+ super_doc, /* tp_doc */
+ super_traverse, /* tp_traverse */
+ 0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
@@ -5872,5 +5872,5 @@
super_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+ PyObject_GC_Del, /* tp_free */
};
1
0