Discussion:
[Python-3000-checkins] r66456 - in python/branches/py3k: Lib/lib2to3 Lib/lib2to3/Grammar.txt Lib/lib2to3/fixes/fix_metaclass.py Lib/lib2to3/fixes/fix_print.py Lib/lib2to3/tests/data/py2_test_grammar.py Lib/lib2to3/tests/data/py3_test_grammar.py Lib/lib2to3/tests/test_fixers.py
benjamin.peterson
2008-09-13 18:37:10 UTC
Permalink
Author: benjamin.peterson
Date: Sat Sep 13 20:37:09 2008
New Revision: 66456

Log:
Merged revisions 66453 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/trunk

................
r66453 | benjamin.peterson | 2008-09-13 12:43:19 -0500 (Sat, 13 Sep 2008) | 24 lines

Merged revisions 66191,66418,66438,66445 via svnmerge from
svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3

........
r66191 | benjamin.peterson | 2008-09-03 17:00:52 -0500 (Wed, 03 Sep 2008) | 1 line

update the Grammar file after recent syntax changes
........
r66418 | benjamin.peterson | 2008-09-12 18:49:48 -0500 (Fri, 12 Sep 2008) | 1 line

a trival fix to get a few more print corner cases #2899
........
r66438 | benjamin.peterson | 2008-09-12 21:32:30 -0500 (Fri, 12 Sep 2008) | 5 lines

add Jack Diederich's fixer for metaclass syntax #2366

my contribution to this was adding a few tests and fixing a few bugs
I also reviewed it (Jack is a committer)
........
r66445 | benjamin.peterson | 2008-09-13 10:50:00 -0500 (Sat, 13 Sep 2008) | 1 line

add a few more tests concerning int literals and weird spacing
........
................


Added:
python/branches/py3k/Lib/lib2to3/fixes/fix_metaclass.py
- copied unchanged from r66453, /python/trunk/Lib/lib2to3/fixes/fix_metaclass.py
Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Lib/lib2to3/ (props changed)
python/branches/py3k/Lib/lib2to3/Grammar.txt
python/branches/py3k/Lib/lib2to3/fixes/fix_print.py
python/branches/py3k/Lib/lib2to3/tests/data/py2_test_grammar.py
python/branches/py3k/Lib/lib2to3/tests/data/py3_test_grammar.py
python/branches/py3k/Lib/lib2to3/tests/test_fixers.py

Modified: python/branches/py3k/Lib/lib2to3/Grammar.txt
==============================================================================
--- python/branches/py3k/Lib/lib2to3/Grammar.txt (original)
+++ python/branches/py3k/Lib/lib2to3/Grammar.txt Sat Sep 13 20:37:09 2008
@@ -138,7 +138,9 @@

classdef: 'class' NAME ['(' [arglist] ')'] ':' suite

-arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
+arglist: (argument ',')* (argument [',']
+ |'*' test (',' argument)* [',' '**' test]
+ |'**' test)
argument: test [comp_for] | test '=' test # Really [keyword '='] test

comp_iter: comp_for | comp_if

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_print.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_print.py (original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_print.py Sat Sep 13 20:37:09 2008
@@ -29,7 +29,7 @@
class FixPrint(fixer_base.ConditionalFix):

PATTERN = """
- simple_stmt< bare='print' any > | print_stmt
+ simple_stmt< any* bare='print' any* > | print_stmt
"""

skip_on = '__future__.print_function'

Modified: python/branches/py3k/Lib/lib2to3/tests/data/py2_test_grammar.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/data/py2_test_grammar.py (original)
+++ python/branches/py3k/Lib/lib2to3/tests/data/py2_test_grammar.py Sat Sep 13 20:37:09 2008
@@ -1,4 +1,4 @@
-# Python 2's Lib/test/test_grammar.py (r54061)
+# Python 2's Lib/test/test_grammar.py (r66189)

# Python test set -- part 1, grammar.
# This just tests whether the parser accepts them all.
@@ -30,13 +30,15 @@

def testPlainIntegers(self):
self.assertEquals(0xff, 255)
- self.assertEquals(0o377, 255)
- self.assertEquals(2147483647, 0o17777777777)
- from sys import maxsize
+ self.assertEquals(0377, 255)
+ self.assertEquals(2147483647, 017777777777)
+ # "0x" is not a valid literal
+ self.assertRaises(SyntaxError, eval, "0x")
+ from sys import maxint
if maxint == 2147483647:
- self.assertEquals(-2147483647-1, -0o20000000000)
+ self.assertEquals(-2147483647-1, -020000000000)
# XXX -2147483648
- self.assert_(0o37777777777 > 0)
+ self.assert_(037777777777 > 0)
self.assert_(0xffffffff > 0)
for s in '2147483648', '040000000000', '0x100000000':
try:
@@ -44,8 +46,8 @@
except OverflowError:
self.fail("OverflowError on huge integer literal %r" % s)
elif maxint == 9223372036854775807:
- self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000)
- self.assert_(0o1777777777777777777777 > 0)
+ self.assertEquals(-9223372036854775807-1, -01000000000000000000000)
+ self.assert_(01777777777777777777777 > 0)
self.assert_(0xffffffffffffffff > 0)
for s in '9223372036854775808', '02000000000000000000000', \
'0x10000000000000000':
@@ -57,14 +59,14 @@
self.fail('Weird maxint value %r' % maxint)

def testLongIntegers(self):
- x = 0
- x = 0
- x = 0xffffffffffffffff
- x = 0xffffffffffffffff
- x = 0o77777777777777777
- x = 0o77777777777777777
- x = 123456789012345678901234567890
- x = 123456789012345678901234567890
+ x = 0L
+ x = 0l
+ x = 0xffffffffffffffffL
+ x = 0xffffffffffffffffl
+ x = 077777777777777777L
+ x = 077777777777777777l
+ x = 123456789012345678901234567890L
+ x = 123456789012345678901234567890l

def testFloats(self):
x = 3.14
@@ -152,27 +154,27 @@
f1(*(), **{})
def f2(one_argument): pass
def f3(two, arguments): pass
- def f4(two, xxx_todo_changeme): (compound, (argument, list)) = xxx_todo_changeme; pass
- def f5(xxx_todo_changeme1, two): (compound, first) = xxx_todo_changeme1; pass
- self.assertEquals(f2.__code__.co_varnames, ('one_argument',))
- self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments'))
+ def f4(two, (compound, (argument, list))): pass
+ def f5((compound, first), two): pass
+ self.assertEquals(f2.func_code.co_varnames, ('one_argument',))
+ self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments'))
if sys.platform.startswith('java'):
- self.assertEquals(f4.__code__.co_varnames,
+ self.assertEquals(f4.func_code.co_varnames,
('two', '(compound, (argument, list))', 'compound', 'argument',
'list',))
- self.assertEquals(f5.__code__.co_varnames,
+ self.assertEquals(f5.func_code.co_varnames,
('(compound, first)', 'two', 'compound', 'first'))
else:
- self.assertEquals(f4.__code__.co_varnames,
+ self.assertEquals(f4.func_code.co_varnames,
('two', '.1', 'compound', 'argument', 'list'))
- self.assertEquals(f5.__code__.co_varnames,
+ self.assertEquals(f5.func_code.co_varnames,
('.0', 'two', 'compound', 'first'))
def a1(one_arg,): pass
def a2(two, args,): pass
def v0(*rest): pass
def v1(a, *rest): pass
def v2(a, b, *rest): pass
- def v3(a, xxx_todo_changeme2, *rest): (b, c) = xxx_todo_changeme2; return a, b, c, rest
+ def v3(a, (b, c), *rest): return a, b, c, rest

f1()
f2(1)
@@ -201,9 +203,9 @@
# ceval unpacks the formal arguments into the first argcount names;
# thus, the names nested inside tuples must appear after these names.
if sys.platform.startswith('java'):
- self.assertEquals(v3.__code__.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
+ self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
else:
- self.assertEquals(v3.__code__.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
+ self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
def d01(a=1): pass
d01()
@@ -277,17 +279,29 @@
d22v(*(1, 2, 3, 4))
d22v(1, 2, *(3, 4, 5))
d22v(1, *(2, 3), **{'d': 4})
- def d31v(xxx_todo_changeme3): (x) = xxx_todo_changeme3; pass
+ def d31v((x)): pass
d31v(1)
- def d32v(xxx_todo_changeme4): (x,) = xxx_todo_changeme4; pass
+ def d32v((x,)): pass
d32v((1,))

+ # keyword arguments after *arglist
+ def f(*args, **kwargs):
+ return args, kwargs
+ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4),
+ {'x':2, 'y':5}))
+ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
+ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+
+ # Check ast errors in *args and *kwargs
+ check_syntax_error(self, "f(*g(1=2))")
+ check_syntax_error(self, "f(**g(1=2))")
+
def testLambdef(self):
### lambdef: 'lambda' [varargslist] ':' test
l1 = lambda : 0
self.assertEquals(l1(), 0)
l2 = lambda : a[d] # XXX just testing the expression
- l3 = lambda : [2 < x for x in [-1, 3, 0]]
+ l3 = lambda : [2 < x for x in [-1, 3, 0L]]
self.assertEquals(l3(), [0, 1, 0])
l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
self.assertEquals(l4(), 1)
@@ -295,6 +309,7 @@
self.assertEquals(l5(1, 2), 5)
self.assertEquals(l5(1, 2, 3), 6)
check_syntax_error(self, "lambda x: x = 2")
+ check_syntax_error(self, "lambda (None,): None")

### stmt: simple_stmt | compound_stmt
# Tested below
@@ -325,36 +340,36 @@

def testPrintStmt(self):
# 'print' (test ',')* [test]
- import io
+ import StringIO

# Can't test printing to real stdout without comparing output
# which is not available in unittest.
save_stdout = sys.stdout
- sys.stdout = io.StringIO()
+ sys.stdout = StringIO.StringIO()

- print(1, 2, 3)
- print(1, 2, 3, end=' ')
- print()
- print(0 or 1, 0 or 1, end=' ')
- print(0 or 1)
+ print 1, 2, 3
+ print 1, 2, 3,
+ print
+ print 0 or 1, 0 or 1,
+ print 0 or 1

# 'print' '>>' test ','
- print(1, 2, 3, file=sys.stdout)
- print(1, 2, 3, end=' ', file=sys.stdout)
- print(file=sys.stdout)
- print(0 or 1, 0 or 1, end=' ', file=sys.stdout)
- print(0 or 1, file=sys.stdout)
+ print >> sys.stdout, 1, 2, 3
+ print >> sys.stdout, 1, 2, 3,
+ print >> sys.stdout
+ print >> sys.stdout, 0 or 1, 0 or 1,
+ print >> sys.stdout, 0 or 1

# test printing to an instance
class Gulp:
def write(self, msg): pass

gulp = Gulp()
- print(1, 2, 3, file=gulp)
- print(1, 2, 3, end=' ', file=gulp)
- print(file=gulp)
- print(0 or 1, 0 or 1, end=' ', file=gulp)
- print(0 or 1, file=gulp)
+ print >> gulp, 1, 2, 3
+ print >> gulp, 1, 2, 3,
+ print >> gulp
+ print >> gulp, 0 or 1, 0 or 1,
+ print >> gulp, 0 or 1

# test print >> None
def driver():
@@ -368,13 +383,13 @@

# we should see this once
def tellme(file=sys.stdout):
- print('hello world', file=file)
+ print >> file, 'hello world'

driver()

# we should not see this at all
def tellme(file=None):
- print('goodbye universe', file=file)
+ print >> file, 'goodbye universe'

driver()

@@ -461,7 +476,7 @@
continue
except:
raise
- if count > 2 or big_hippo != 1:
+ if count > 2 or big_hippo <> 1:
self.fail("continue then break in try/except in loop broken!")
test_inner()

@@ -478,7 +493,7 @@

def testRaise(self):
# 'raise' test [',' test]
- try: raise RuntimeError('just testing')
+ try: raise RuntimeError, 'just testing'
except RuntimeError: pass
try: raise KeyboardInterrupt
except KeyboardInterrupt: pass
@@ -506,33 +521,33 @@
# 'exec' expr ['in' expr [',' expr]]
z = None
del z
- exec('z=1+1\n')
+ exec 'z=1+1\n'
if z != 2: self.fail('exec \'z=1+1\'\\n')
del z
- exec('z=1+1')
+ exec 'z=1+1'
if z != 2: self.fail('exec \'z=1+1\'')
z = None
del z
import types
if hasattr(types, "UnicodeType"):
- exec(r"""if 1:
+ exec r"""if 1:
exec u'z=1+1\n'
if z != 2: self.fail('exec u\'z=1+1\'\\n')
del z
exec u'z=1+1'
- if z != 2: self.fail('exec u\'z=1+1\'')""")
+ if z != 2: self.fail('exec u\'z=1+1\'')"""
g = {}
- exec('z = 1', g)
- if '__builtins__' in g: del g['__builtins__']
+ exec 'z = 1' in g
+ if g.has_key('__builtins__'): del g['__builtins__']
if g != {'z': 1}: self.fail('exec \'z = 1\' in g')
g = {}
l = {}

import warnings
warnings.filterwarnings("ignore", "global statement", module="<string>")
- exec('global a; a = 1; b = 2', g, l)
- if '__builtins__' in g: del g['__builtins__']
- if '__builtins__' in l: del l['__builtins__']
+ exec 'global a; a = 1; b = 2' in g, l
+ if g.has_key('__builtins__'): del g['__builtins__']
+ if l.has_key('__builtins__'): del l['__builtins__']
if (g, l) != ({'a':1}, {'b':2}):
self.fail('exec ... in g (%s), l (%s)' %(g,l))

@@ -544,7 +559,7 @@
assert 1, lambda x:x+1
try:
assert 0, "msg"
- except AssertionError as e:
+ except AssertionError, e:
self.assertEquals(e.args[0], "msg")
else:
if __debug__:
@@ -572,6 +587,15 @@
while 0: pass
else: pass

+ # Issue1920: "while 0" is optimized away,
+ # ensure that the "else" clause is still present.
+ x = 0
+ while 0:
+ x = 1
+ else:
+ x = 2
+ self.assertEquals(x, 2)
+
def testFor(self):
# 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
for i in 1, 2, 3: pass
@@ -602,7 +626,7 @@
def testTry(self):
### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
### | 'try' ':' suite 'finally' ':' suite
- ### except_clause: 'except' [expr [',' expr]]
+ ### except_clause: 'except' [expr [('as' | ',') expr]]
try:
1/0
except ZeroDivisionError:
@@ -611,7 +635,7 @@
pass
try: 1/0
except EOFError: pass
- except TypeError, msg: pass
+ except TypeError as msg: pass
except RuntimeError, msg: pass
except: pass
else: pass
@@ -655,7 +679,7 @@
x = (1 == 1)
if 1 == 1: pass
if 1 != 1: pass
- if 1 != 1: pass
+ if 1 <> 1: pass
if 1 < 1: pass
if 1 > 1: pass
if 1 <= 1: pass
@@ -664,7 +688,7 @@
if 1 is not 1: pass
if 1 in (): pass
if 1 not in (): pass
- if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 != 1 in 1 not in 1 is 1 is not 1: pass
+ if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass

def testBinaryMaskOps(self):
x = 1 & 1
@@ -747,9 +771,9 @@
x = {'one': 1, 'two': 2,}
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}

- x = repr(x)
- x = repr(1 or 2 or 3)
- self.assertEqual(repr((1,2)), '(1, 2)')
+ x = `x`
+ x = `1 or 2 or 3`
+ self.assertEqual(`1,2`, '(1, 2)')

x = x
x = 'x'
@@ -770,6 +794,16 @@
def meth1(self): pass
def meth2(self, arg): pass
def meth3(self, a1, a2): pass
+ # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+ # decorators: decorator+
+ # decorated: decorators (classdef | funcdef)
+ def class_decorator(x):
+ x.decorated = True
+ return x
+ @class_decorator
+ class G:
+ pass
+ self.assertEqual(G.decorated, True)

def testListcomps(self):
# list comprehension tests
@@ -837,9 +871,9 @@
def testGenexps(self):
# generator expression tests
g = ([x for x in range(10)] for x in range(1))
- self.assertEqual(next(g), [x for x in range(10)])
+ self.assertEqual(g.next(), [x for x in range(10)])
try:
- next(g)
+ g.next()
self.fail('should produce StopIteration exception')
except StopIteration:
pass
@@ -847,7 +881,7 @@
a = 1
try:
g = (a for d in a)
- next(g)
+ g.next()
self.fail('should produce TypeError')
except TypeError:
pass
@@ -892,7 +926,7 @@
# Test ifelse expressions in various cases
def _checkeval(msg, ret):
"helper to check that evaluation of expressions is done correctly"
- print(x)
+ print x
return ret

self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])

Modified: python/branches/py3k/Lib/lib2to3/tests/data/py3_test_grammar.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/data/py3_test_grammar.py (original)
+++ python/branches/py3k/Lib/lib2to3/tests/data/py3_test_grammar.py Sat Sep 13 20:37:09 2008
@@ -8,7 +8,7 @@
# regression test, the filterwarnings() call has been added to
# regrtest.py.

-from test.test_support import run_unittest, check_syntax_error
+from test.support import run_unittest, check_syntax_error
import unittest
import sys
# testing import *
@@ -32,8 +32,10 @@
self.assertEquals(0o377, 255)
self.assertEquals(2147483647, 0o17777777777)
self.assertEquals(0b1001, 9)
+ # "0x" is not a valid literal
+ self.assertRaises(SyntaxError, eval, "0x")
from sys import maxsize
- if maxint == 2147483647:
+ if maxsize == 2147483647:
self.assertEquals(-2147483647-1, -0o20000000000)
# XXX -2147483648
self.assert_(0o37777777777 > 0)
@@ -45,7 +47,7 @@
x = eval(s)
except OverflowError:
self.fail("OverflowError on huge integer literal %r" % s)
- elif maxint == 9223372036854775807:
+ elif maxsize == 9223372036854775807:
self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000)
self.assert_(0o1777777777777777777777 > 0)
self.assert_(0xffffffffffffffff > 0)
@@ -58,7 +60,7 @@
except OverflowError:
self.fail("OverflowError on huge integer literal %r" % s)
else:
- self.fail('Weird maxint value %r' % maxint)
+ self.fail('Weird maxsize value %r' % maxsize)

def testLongIntegers(self):
x = 0
@@ -263,6 +265,14 @@
d22v(*(1, 2, 3, 4))
d22v(1, 2, *(3, 4, 5))
d22v(1, *(2, 3), **{'d': 4})
+
+ # keyword argument type tests
+ try:
+ str('x', **{b'foo':1 })
+ except TypeError:
+ pass
+ else:
+ self.fail('Bytes should not work as keyword argument names')
# keyword only argument tests
def pos0key1(*, key): return key
pos0key1(key=100)
@@ -274,6 +284,14 @@
pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)

+ # keyword arguments after *arglist
+ def f(*args, **kwargs):
+ return args, kwargs
+ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4),
+ {'x':2, 'y':5}))
+ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
+ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+
# argument annotation tests
def f(x) -> list: pass
self.assertEquals(f.__annotations__, {'return': list})
@@ -308,6 +326,10 @@
def f(*, k=1): return closure
def f() -> int: return closure

+ # Check ast errors in *args and *kwargs
+ check_syntax_error(self, "f(*g(1=2))")
+ check_syntax_error(self, "f(**g(1=2))")
+
def testLambdef(self):
### lambdef: 'lambda' [varargslist] ':' test
l1 = lambda : 0
@@ -321,6 +343,7 @@
self.assertEquals(l5(1, 2), 5)
self.assertEquals(l5(1, 2, 3), 6)
check_syntax_error(self, "lambda x: x = 2")
+ check_syntax_error(self, "lambda (None,): None")
l6 = lambda x, y, *, k=20: x+y+k
self.assertEquals(l6(1,2), 1+2+20)
self.assertEquals(l6(1,2,k=10), 1+2+10)
@@ -498,6 +521,15 @@
while 0: pass
else: pass

+ # Issue1920: "while 0" is optimized away,
+ # ensure that the "else" clause is still present.
+ x = 0
+ while 0:
+ x = 1
+ else:
+ x = 2
+ self.assertEquals(x, 2)
+
def testFor(self):
# 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
for i in 1, 2, 3: pass

Modified: python/branches/py3k/Lib/lib2to3/tests/test_fixers.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/test_fixers.py (original)
+++ python/branches/py3k/Lib/lib2to3/tests/test_fixers.py Sat Sep 13 20:37:09 2008
@@ -385,6 +385,16 @@
a = """print()"""
self.check(b, a)

+ def test_4(self):
+ # from bug 3000
+ b = """print whatever; print"""
+ a = """print(whatever); print()"""
+ self.check(b, a)
+
+ def test_5(self):
+ b = """print; print whatever;"""
+ a = """print(); print(whatever);"""
+
def test_tuple(self):
b = """print (a, b, c)"""
a = """print((a, b, c))"""
@@ -2379,6 +2389,15 @@
a = """b = 0x12"""
self.check(b, a)

+ def test_comments_and_spacing(self):
+ b = """b = 0x12L"""
+ a = """b = 0x12"""
+ self.check(b, a)
+
+ b = """b = 0755 # spam"""
+ a = """b = 0o755 # spam"""
+ self.check(b, a)
+
def test_unchanged_int(self):
s = """5"""
self.unchanged(s)
@@ -3430,6 +3449,133 @@
s = """[i for i in m]"""
self.unchanged(s)

+class Test_metaclass(FixerTestCase):
+
+ fixer = 'metaclass'
+
+ def test_unchanged(self):
+ self.unchanged("class X(): pass")
+ self.unchanged("class X(object): pass")
+ self.unchanged("class X(object1, object2): pass")
+ self.unchanged("class X(object1, object2, object3): pass")
+ self.unchanged("class X(metaclass=Meta): pass")
+ self.unchanged("class X(b, arg=23, metclass=Meta): pass")
+ self.unchanged("class X(b, arg=23, metaclass=Meta, other=42): pass")
+
+ s = """
+ class X:
+ def __metaclass__(self): pass
+ """
+ self.unchanged(s)
+
+ def test_comments(self):
+ b = """
+ class X:
+ # hi
+ __metaclass__ = AppleMeta
+ """
+ a = """
+ class X(metaclass=AppleMeta):
+ # hi
+ pass
+ """
+ self.check(b, a)
+
+ b = """
+ class X:
+ __metaclass__ = Meta
+ # Bedtime!
+ """
+ a = """
+ class X(metaclass=Meta):
+ pass
+ # Bedtime!
+ """
+ self.check(b, a)
+
+ def test_meta(self):
+ # no-parent class, odd body
+ b = """
+ class X():
+ __metaclass__ = Q
+ pass
+ """
+ a = """
+ class X(metaclass=Q):
+ pass
+ """
+ self.check(b, a)
+
+ # one parent class, no body
+ b = """class X(object): __metaclass__ = Q"""
+ a = """class X(object, metaclass=Q): pass"""
+ self.check(b, a)
+
+
+ # one parent, simple body
+ b = """
+ class X(object):
+ __metaclass__ = Meta
+ bar = 7
+ """
+ a = """
+ class X(object, metaclass=Meta):
+ bar = 7
+ """
+ self.check(b, a)
+
+ b = """
+ class X:
+ __metaclass__ = Meta; x = 4; g = 23
+ """
+ a = """
+ class X(metaclass=Meta):
+ x = 4; g = 23
+ """
+ self.check(b, a)
+
+ # one parent, simple body, __metaclass__ last
+ b = """
+ class X(object):
+ bar = 7
+ __metaclass__ = Meta
+ """
+ a = """
+ class X(object, metaclass=Meta):
+ bar = 7
+ """
+ self.check(b, a)
+
+ # redefining __metaclass__
+ b = """
+ class X():
+ __metaclass__ = A
+ __metaclass__ = B
+ bar = 7
+ """
+ a = """
+ class X(metaclass=B):
+ bar = 7
+ """
+ self.check(b, a)
+
+ # multiple inheritance, simple body
+ b = """
+ class X(clsA, clsB):
+ __metaclass__ = Meta
+ bar = 7
+ """
+ a = """
+ class X(clsA, clsB, metaclass=Meta):
+ bar = 7
+ """
+ self.check(b, a)
+
+ # keywords in the class statement
+ b = """class m(a, arg=23): __metaclass__ = Meta"""
+ a = """class m(a, arg=23, metaclass=Meta): pass"""
+ self.check(b, a)
+

if __name__ == "__main__":
import __main__

Loading...