-- Test cases for type checking mypy programs using full stubs and running
-- using CPython (Python 2 mode).
--
-- These are mostly regression tests -- no attempt is made to make these
-- complete.


[case testAbs2_python2]
n = None  # type: int
f = None  # type: float
n = abs(1)
abs(1) + 'x'  # Error
f = abs(1.1)
abs(1.1) + 'x'  # Error
[out]
_program.py:4: error: Unsupported operand types for + ("int" and "str")
_program.py:6: error: Unsupported operand types for + ("float" and "str")

[case testUnicode_python2]
x = unicode('xyz', 'latin1')
print x
x = u'foo'
print repr(x)
[out]
xyz
u'foo'

[case testXrangeAndRange_python2]
for i in xrange(2):
    print i
for i in range(3):
    print i
[out]
0
1
0
1
2

[case testIterator_python2]
import typing, sys
x = iter('bar')
print x.next(), x.next()
[out]
b a

[case testEncodeAndDecode_python2]
print 'a'.encode('latin1')
print 'b'.decode('latin1')
print u'c'.encode('latin1')
print u'd'.decode('latin1')
[out]
a
b
c
d

[case testHasKey_python2]
d = {1: 'x'}
print d.has_key(1)
print d.has_key(2)
[out]
True
False

[case testIntegerDivision_python2]
x = 1 / 2
x()
[out]
_program.py:2: error: "int" not callable

[case testFloatDivision_python2]
x = 1.0 / 2.0
x = 1.0 / 2
x = 1 / 2.0
x = 1.5
[out]

[case testAnyStr_python2]
from typing import AnyStr
def f(x): # type: (AnyStr) -> AnyStr
    if isinstance(x, str):
        return 'foo'
    else:
        return u'zar'
print f('')
print f(u'')
[out]
foo
zar

[case testGenericPatterns_python2]
from typing import Pattern
import re
p = None  # type: Pattern[unicode]
p = re.compile(u'foo*')
b = None  # type: Pattern[str]
b = re.compile('foo*')
print(p.match(u'fooo').group(0))
[out]
fooo

[case testGenericMatch_python2]
from typing import Match
import re
def f(m): # type: (Match[str]) -> None
    print(m.group(0))
f(re.match('x*', 'xxy'))
[out]
xx

[case testFromFuturePrintFunction_python2]
from __future__ import print_function
print('a', 'b')
[out]
a b

[case testFromFutureImportUnicodeLiterals_python2]
from __future__ import unicode_literals
print '>', ['a', b'b', u'c']
[out]
> [u'a', 'b', u'c']

[case testUnicodeLiteralsKwargs_python2]
from __future__ import unicode_literals
def f(**kwargs):  # type: (...) -> None
  pass
params = {'a': 'b'}
f(**params)
[out]

[case testUnicodeStringKwargs_python2]
def f(**kwargs):  # type: (...) -> None
  pass
params = {u'a': 'b'}
f(**params)
[out]

[case testStrKwargs_python2]
def f(**kwargs):  # type: (...) -> None
  pass
params = {'a': 'b'}
f(**params)
[out]

[case testFromFutureImportUnicodeLiterals2_python2]
from __future__ import unicode_literals
def f(x): # type: (str) -> None
  pass
f(b'')
f(u'')
f('')
[out]
_program.py:5: error: Argument 1 to "f" has incompatible type "unicode"; expected "str"
_program.py:6: error: Argument 1 to "f" has incompatible type "unicode"; expected "str"

[case testStrUnicodeCompatibility_python2]
def f(s): # type: (unicode) -> None
    pass
f(u'')
f('')
[out]

[case testStrUnicodeCompatibilityInBuiltins_python2]
'x'.count('x')
'x'.count(u'x')
[out]

[case testTupleAsSubtypeOfSequence_python2]
from typing import TypeVar, Sequence
T = TypeVar('T')
def f(a): # type: (Sequence[T]) -> None
    print a
f(tuple())
[out]
()

[case testIOTypes_python2]
from typing import IO, TextIO, BinaryIO, Any
class X(IO[str]): pass
class Y(TextIO): pass
class Z(BinaryIO): pass
[out]

[case testOpenReturnType_python2]
import typing
f = open('/tmp/xyz', 'w')
f.write(u'foo')
f.write('bar')
f.close()
[out]
_program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "unicode"; expected "str"

[case testPrintFunctionWithFileArg_python2]
from __future__ import print_function
import typing
if 1 == 2: # Don't want to run the code below, since it would create a file.
    f = open('/tmp/xyz', 'w')
    print('foo', file=f)
    f.close()
print('ok')
[out]
ok

[case testStringIO_python2]
import typing
import io
c = io.StringIO()
c.write(u'\x89')
print(repr(c.getvalue()))
[out]
u'\x89'

[case testBytesIO_python2]
import typing
import io
c = io.BytesIO()
c.write('\x89')
print(repr(c.getvalue()))
[out]
'\x89'

[case testTextIOWrapper_python2]
import typing
import io
b = io.BytesIO(u'\xab'.encode('utf8'))
w = io.TextIOWrapper(b, encoding='utf8')
print(repr(w.read()))
[out]
u'\xab'

[case testIoOpen_python2]
import typing
import io
if 1 == 2: # Only type check, do not execute
    f = io.open('/tmp/xyz', 'w', encoding='utf8')
    f.write(u'\xab')
    f.close()
print 'ok'
[out]
ok

[case testStrAdd_python2]
import typing
s = ''
u = u''
n = 0
n = s + '' # E
s = s + u'' # E
[out]
_program.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
_program.py:6: error: Incompatible types in assignment (expression has type "unicode", variable has type "str")

[case testStrJoin_python2]
import typing
s = ''
u = u''
n = 0
n = ''.join([''])   # Error
s = ''.join([u''])  # Error
[out]
_program.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
_program.py:6: error: Incompatible types in assignment (expression has type "unicode", variable has type "str")

[case testNamedTuple_python2]
from typing import NamedTuple
from collections import namedtuple
X = namedtuple('X', ['a', 'b'])
x = X(a=1, b='s')
x.c
x.a

N = NamedTuple(u'N', [(u'x', int)])
n = namedtuple(u'n', u'x y')

[out]
_program.py:5: error: "X" has no attribute "c"

[case testAssignToComplexReal_python2]
import typing
x = 4j
y = x.real
y = x         # Error
x.imag = 2.0  # Error
[out]
_program.py:4: error: Incompatible types in assignment (expression has type "complex", variable has type "float")
_program.py:5: error: Property "imag" defined in "complex" is read-only

[case testComplexArithmetic_python2]
import typing
print 5 + 8j
print 3j * 2.0
print 4j / 2.0
[out]
(5+8j)
6j
2j

[case testSuperNew_python2]
from typing import Dict, Any
class MyType(type):
    def __new__(cls, name, bases, namespace):
        # type: (str, tuple, Dict[str, Any]) -> type
        return super(MyType, cls).__new__(cls, name + 'x', bases, namespace)
class A(object):
    __metaclass__ = MyType
print(type(A()).__name__)
[out]
Ax

[case testUnicodeAndOverloading_python2]
from m import f
f(1)
f('')
f(u'')
f(b'')
[file m.pyi]
from typing import overload
@overload
def f(x): # type: (bytearray) -> int
  pass
@overload
def f(x): # type: (unicode) -> int
  pass
[out]
_program.py:2: error: No overload variant of "f" matches argument type "int"
_program.py:2: note: Possible overload variants:
_program.py:2: note:     def f(x: bytearray) -> int
_program.py:2: note:     def f(x: unicode) -> int

[case testByteArrayStrCompatibility_python2]
def f(x): # type: (str) -> None
    pass
f(bytearray('foo'))

[case testAbstractProperty_python2]
from abc import abstractproperty, ABCMeta
class A:
    __metaclass__ = ABCMeta
    @abstractproperty
    def x(self): # type: () -> int
        pass
class B(A):
    @property
    def x(self): # type: () -> int
        return 3
b = B()
print b.x + 1
[out]
4

[case testReModuleBytes_python2]
# Regression tests for various overloads in the re module -- bytes version
import re
if False:
    bre = b'a+'
    bpat = re.compile(bre)
    bpat = re.compile(bpat)
    re.search(bre, b'').groups()
    re.search(bre, u'')
    re.search(bpat, b'').groups()
    re.search(bpat, u'')
    # match(), split(), findall(), finditer() are much the same, so skip those.
    # sub(), subn() have more overloads and we are checking these:
    re.sub(bre, b'', b'') + b''
    re.sub(bpat, b'', b'') + b''
    re.sub(bre, lambda m: b'', b'') + b''
    re.sub(bpat, lambda m: b'', b'') + b''
    re.subn(bre, b'', b'')[0] + b''
    re.subn(bpat, b'', b'')[0] + b''
    re.subn(bre, lambda m: b'', b'')[0] + b''
    re.subn(bpat, lambda m: b'', b'')[0] + b''
[out]

[case testReModuleString_python2]
# Regression tests for various overloads in the re module -- string version
import re
ure = u'a+'
upat = re.compile(ure)
upat = re.compile(upat)
re.search(ure, u'a').groups()
re.search(ure, b'') # This ought to be an error, but isn't because of bytes->unicode equivalence
re.search(upat, u'a').groups()
re.search(upat, b'') # This ought to be an error, but isn't because of bytes->unicode equivalence
# match(), split(), findall(), finditer() are much the same, so skip those.
# sus(), susn() have more overloads and we are checking these:
re.sub(ure, u'', u'') + u''
re.sub(upat, u'', u'') + u''
re.sub(ure, lambda m: u'', u'') + u''
re.sub(upat, lambda m: u'', u'') + u''
re.subn(ure, u'', u'')[0] + u''
re.subn(upat, u'', u'')[0] + u''
re.subn(ure, lambda m: u'', u'')[0] + u''
re.subn(upat, lambda m: u'', u'')[0] + u''
[out]

[case testYieldRegressionTypingAwaitable_python2]
# Make sure we don't reference typing.Awaitable in Python 2 mode.
def g():  # type: () -> int
    yield
[out]
_program.py:2: error: The return type of a generator function should be "Generator" or one of its supertypes

[case testOsPathJoinWorksWithAny_python2]
import os
def f():  # no annotation
   return 'tests'
path = 'test'
path = os.path.join(f(), 'test.py')
[out]

[case testBytesWorkInPython2WithFullStubs_python2]
MYPY = False
if MYPY:
    import lib
[file lib.pyi]
x = b'abc'
[out]
