-- Type checker test cases for Python 2.x mode.


[case testUnicode]
u = u'foo'
u = unicode()
s = ''
s = u'foo' # E: Incompatible types in assignment (expression has type "unicode", variable has type "str")
s = b'foo'
[builtins_py2 fixtures/python2.pyi]

[case testTypeVariableUnicode]
from typing import TypeVar
T = TypeVar(u'T')

[case testPrintStatement]
print ''() # E: "str" not callable
print 1, 1() # E: "int" not callable

[case testPrintStatementWithTarget]
class A:
    def write(self, s):
        # type: (str) -> None
        pass

print >>A(), ''
print >>None, ''
print >>1, '' # E: "int" has no attribute "write"
print >>(None + ''), None # E: Unsupported left operand type for + ("None")

[case testDivision]
class A:
    def __div__(self, x):
        # type: (int) -> str
        pass
s = A() / 1
s = ''
s = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str")

[case testStrUnicodeCompatibility]
import typing
def f(x):
    # type: (unicode) -> None
    pass
f('')
f(u'')
f(b'')
[builtins_py2 fixtures/python2.pyi]

[case testStaticMethodWithCommentSignature]
class A:
    @staticmethod
    def f(x): # type: (int) -> str
        return ''
A.f(1)
A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
[builtins_py2 fixtures/staticmethod.pyi]

[case testRaiseTuple]
import typing
raise BaseException, "a"
raise BaseException, "a", None
[builtins_py2 fixtures/exception.pyi]

[case testTryExceptWithTuple]
try:
    None
except BaseException, e:
    e() # E: "BaseException" not callable
[builtins_py2 fixtures/exception.pyi]

[case testTryExceptUnsupported]
try:
    pass
except BaseException, (e, f):  # E: Sorry, `except <expr>, <anything but a name>` is not supported
    pass
try:
    pass
except BaseException, [e, f, g]:  # E: Sorry, `except <expr>, <anything but a name>` is not supported
    pass
try:
    pass
except BaseException, e[0]:  # E: Sorry, `except <expr>, <anything but a name>` is not supported
    pass
[builtins_py2 fixtures/exception.pyi]

[case testAlternateNameSuggestions]
class Foo(object):
    def say_hello(self):
        pass
    def say_hell(self):
        pass
    def say_hullo(self):
        pass
    def say_goodbye(self):
        pass
    def go_away(self):
        pass
    def go_around(self):
        pass
    def append(self):
        pass
    def extend(self):
        pass
    def _add(self):
        pass

f = Foo()
f.say_hallo() # E: "Foo" has no attribute "say_hallo"; maybe "say_hullo", "say_hello", or "say_hell"?
f.go_array() # E: "Foo" has no attribute "go_array"; maybe "go_away"?
f.add() # E: "Foo" has no attribute "add"; maybe "append", "extend", or "_add"?

[case testTupleArgListDynamicallyTyped]
def f(x, (y, z)):
    x = y + z
f(1, 1)
f(1, (1, 2))

[case testTupleArgListAnnotated]
from typing import Tuple
def f(x, (y, z)): # type: (object, Tuple[int, str]) -> None
    x() # E
    y() # E
    z() # E
f(object(), (1, ''))
f(1, 1) # E
[builtins_py2 fixtures/tuple.pyi]
[out]
main:3: error: "object" not callable
main:4: error: "int" not callable
main:5: error: "str" not callable
main:7: error: Argument 2 to "f" has incompatible type "int"; expected "Tuple[int, str]"

[case testNestedTupleArgListAnnotated]
from typing import Tuple
def f(x, (y, (a, b))): # type: (object, Tuple[int, Tuple[str, int]]) -> None
    x() # E
    y() # E
    a() # E
    b() # E
f(object(), (1, ('', 2)))
f(1, 1) # E
[builtins fixtures/tuple.pyi]
[out]
main:3: error: "object" not callable
main:4: error: "int" not callable
main:5: error: "str" not callable
main:6: error: "int" not callable
main:8: error: Argument 2 to "f" has incompatible type "int"; expected "Tuple[int, Tuple[str, int]]"

[case testBackquoteExpr]
`1`.x # E: "str" has no attribute "x"

[case testPython2OnlyStdLibModuleWithoutStub]
import asyncio
import Bastion
[out]
main:1: error: Cannot find module named 'asyncio'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: No library stub file for standard library module 'Bastion'
main:2: note: (Stub files are from https://github.com/python/typeshed)

[case testImportFromPython2Builtin]
from __builtin__ import int as i
x = 1 # type: i
y = '' # type: i  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testImportPython2Builtin]
import __builtin__
x = 1 # type: __builtin__.int
y = '' # type: __builtin__.int  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testImportAsPython2Builtin]
import __builtin__ as bi
x = 1 # type: bi.int
y = '' # type: bi.int  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testImportFromPython2BuiltinOverridingDefault]
from __builtin__ import int
x = 1 # type: int
y = '' # type: int  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

-- Copied from check-functions.test
[case testEllipsisWithArbitraryArgsOnBareFunctionInPython2]
def f(x, y, z): # type: (...) -> None
    pass

-- Copied from check-functions.test
[case testEllipsisWithSomethingAfterItFailsInPython2]
def f(x, y, z): # type: (..., int) -> None
    pass
[out]
main:1: error: Ellipses cannot accompany other argument types in function type signature.

[case testLambdaTupleArgInPython2]
f = lambda (x, y): x + y
f((0, 0))
[out]

[case testLambdaSingletonTupleArgInPython2]
f = lambda (x,): x + 1
f((0,))
[out]

[case testLambdaNoTupleArgInPython2]
f = lambda (x): x + 1
f(0)
[out]

[case testDefTupleEdgeCasesPython2]
def f((x,)): return x
def g((x)): return x
f(0) + g(0)
[out]

[case testLambdaAsSortKeyForTuplePython2]
from typing import Any, Tuple, Callable
def bar(key):
    # type: (Callable[[Tuple[int, int]], int]) -> int
    pass
def foo():
    # type: () -> int
    return bar(key=lambda (a, b): a)
[out]

[case testImportBuiltins]

import __builtin__
__builtin__.str

[case testUnicodeAlias]
from typing import List
Alias = List[u'Foo']
class Foo: pass
[builtins_py2 fixtures/python2.pyi]

[case testExec]
exec('print 1 + 1')

[case testUnicodeDocStrings]
# flags: --python-version=2.7
__doc__ = u"unicode"

class A:
    u"unicode"

def f():
    # type: () -> None
    u"unicode"

[case testMetaclassBasics]
class M(type):
    x = 0  # type: int
    def test(cls):
        # type: () -> str
        return "test"

class A(object):
    __metaclass__ = M

reveal_type(A.x) # E: Revealed type is 'builtins.int'
reveal_type(A.test()) # E: Revealed type is 'builtins.str'

[case testImportedMetaclass]
import m

class A(object):
    __metaclass__ = m.M

reveal_type(A.x) # E: Revealed type is 'builtins.int'
reveal_type(A.test()) # E: Revealed type is 'builtins.str'
[file m.py]
class M(type):
    x = 0
    def test(cls):
        # type: () -> str
        return "test"

[case testDynamicMetaclass]
class C(object):
    __metaclass__ = int()  # E: Dynamic metaclass not supported for 'C'

[case testMetaclassDefinedAsClass]
class C(object):
    class __metaclass__: pass # E: Metaclasses defined as inner classes are not supported

[case testErrorInMetaclass]
x = 0
class A(object):
    __metaclass__ = m.M  # E: Name 'm' is not defined
class B(object):
    __metaclass__ = M  # E: Name 'M' is not defined

[case testMetaclassAndSkippedImportInPython2]
# flags: --ignore-missing-imports
from missing import M
class A(object):
    __metaclass__ = M
    y = 0
reveal_type(A.y) # E: Revealed type is 'builtins.int'
A.x # E: "Type[A]" has no attribute "x"

[case testAnyAsBaseOfMetaclass]
from typing import Any, Type
M = None  # type: Any
class MM(M): pass
class A(object):
    __metaclass__ = MM

[case testSelfTypeNotSelfType2]
class A:
    def g(self):
        # type: (None) -> None
        pass
[out]
main:2: error: Invalid type for self, or extra argument type in function annotation
main:2: note: (Hint: typically annotations omit the type for self)

[case testSuper]
class A:
    def f(self): # type: () -> None
        pass
class B(A):
    def g(self): # type: () -> None
        super(B, self).f()
        super().f() # E: Too few arguments for "super"
