"""
This file contains nearly every legal token and grammar in Python.
Taken from https://github.com/erezsh/plyplus (MIT licensed) and
modified for Python 3.3+ and 2.7.
"""

# Python 2 produces different ast for print() if print_function is not imported
from __future__ import print_function, with_statement 

# Might as well try the other imports here
import a
import a.b
import a.b.c
import a.b.c.d.e.f.g.h

import a as A
import a as A, b as B
import a.b as AB, a.b as B, a.b.c

from mod1 import mod2
from mod1.mod2 import mod3

from qmod import *
from qmod.qmod2 import *
from a1 import a1

from a import (xrt,
   yrt,
   zrt,
   zrt2)
from a import (xty,
   yty,
   zty,
   zrt2,)
from qwe import *
from qwe.wer import *
from qwe.wer.ert.rty import *

from .a import y
from ..a import y
from ..a import y as z
#from ...qwe import * This is not allowed
from ...a import (y as z, a as a2, t,)
from .................... import a,b,c  # 20 levels
from ...................... import (a,b,c)  # 22 levels

# Name constants
True
False
None

a = 2
a,b = 1, 222
a, = 1,
a, b, = 1, 234
a, b, c
1;
1;27
1;28;
1;29;3
1;21;33;
a.b
a.b.c
a.b.c.d.e.f

# Different number
0xDEADBEEF
0xDEADBEEFCAFE
0xDeadBeefCafe

1.234
10E-3
1.2e+03
-1.9e+03
9j
9.8j
23.45E-9j


# 'factor' operations
a = -1
a = +1
a = ~1
b ** c
a = + + + + 1

# 'comparison' 'comp_op' expressions
a < b
a > b
a == b
a >= b
a <= b
a != b
a in b
a is b
a not in b
a is not b

# arith_expr
1 + 2
1 + 2 + 3
1 + 2 + 3 + 4
1 - 2
1 - 2 - 3
1 - 2 + 3 - 4 + 5
# 
1 - 2 + - 3 - + 4
1 + + + + + 1

# factors
a * 1
a * 1 * 2
b / 2
b / 2 / 3
c % 9
c % 9 % 7
d // 8
d // 8 // 5

a * 1 / 2 / 3 * 9 % 7 // 2 // 1


truth or dare
war and peace
this and that or that and this
a and b and c and d
x or y or z or w
not a
not not a
not not not a
not a or not b or not c
not a or not b and not c and not d

def yield_function():
    yield
    yield 1
    x = yield

@spam.qwe
def eggs():
    pass

@spam
def eggs():
    pass

@spam.qwe()
def eggs():
    pass

@spam1.qwe()
@spam2.qwe()
@spam3.qwe()
@spam3.qwe()
def eggs():
    pass

@spam(1)
def eggs():
    pass

@spam2\
(\
)
def eggs2():
    pass


@spam3\
(\
this,\
blahblabh\
)
def eggs9():
    pass

@spam\
(
**this
)
def qweqwe():
    pass

@spam.\
and_.\
eggs\
(
**this
)
def qweqwe():
    pass


spam()
spam(1)
spam(1,2)
spam(1,2,3)
spam(1,)
spam(1,2,)
spam(1,2,3,)
spam(*a)
spam(**a)
spam(*a,**b)
spam(1, *a)
spam(1, *a, **b)
spam(1, **b)
def spam(x): pass
def spam(x,): pass
def spam(a, b): pass
def spam(a, b,): pass
def spam(a, b, c): pass
def spam(a, *args): pass
def spam(a, *args, **kwargs): pass
def spam(a, **kwargs): pass
def spam(*args, **kwargs): pass
def spam(**kwargs): pass
def spam(*args): pass

def spam(x=1): pass
def spam(x=1,): pass
def spam(a=1, b=2): pass
def spam(a=1, b=2,): pass
def spam(a=1, *args): pass
def spam(a=9.1, *args, **kwargs): pass
def spam(a="", **kwargs): pass
def spam(a,b=1, *args): pass
def spam(a,b=9.1, *args, **kwargs): pass
def spam(a,b="", **kwargs): pass

def spam(a=1, b=2, *args): pass
def spam(a=1, b=2, *args, **kwargs): pass
def spam(a=1, b=2, **kwargs): pass

def spam(a=1, b=2, c=33, d=4): pass


# This show that the compiler module uses the function name location
# for the ast.Function lineno, and not the "def" reserved word.
def \
 spam \
  ( \
  ) \
  : \
  pass

a += 1
a -= 1
a *= 2
a /= 2
a %= 3
a &= 4
a |= 4
a ^= 5
a <<= 6
a >>= 7
a **= 9
a //= 10

b \
 += \
   3

a = b = c
a = b = c = d
# Shows that the ast.Assign gets the lineno from the first '='
a \
 = \
  b \