[case testEmptyClass]
class Empty: pass

def f(e: Empty) -> Empty:
    return e
[file driver.py]
from native import Empty, f

print(isinstance(Empty, type))
print(Empty)
print(str(Empty())[:20])

e = Empty()
print(f(e) is e)
[out]
True
<class 'native.Empty'>
<native.Empty object
True

[case testClassWithFields]
class C:
    x: int
    y: int
    z: 'D'
class D:
    pass
[file driver.py]
from native import C
from testutil import assertRaises

c = C()
assert not hasattr(c, 'x')
assert not hasattr(c, 'y')
c.x = 1
c.y = 2
print(c.x)
print(c.y)
c.x = 10**30
print(c.x)
c.x = 10**30+1
print(c.x)
assert hasattr(c, 'x')
assert hasattr(c, 'y')
assert not hasattr(c, 'z')
with assertRaises(AttributeError, "'C' object attribute 'x' cannot be deleted"):
    del c.x
assert hasattr(c, 'x')
assert hasattr(c, 'y')
with assertRaises(AttributeError, "'C' object attribute 'y' cannot be deleted"):
    del c.y
assert hasattr(c, 'y')
c.x = 10**30+2
print(c.x)
assert hasattr(c, 'x')
[out]
1
2
1000000000000000000000000000000
1000000000000000000000000000001
1000000000000000000000000000002

[case testClassWithDeletableAttributes]
from typing import Any, cast
from testutil import assertRaises

class C:
    __deletable__ = ['x', 'y']
    x: int
    y: int
    z: int

def test_delete() -> None:
    c = C()
    c.x = 1
    c.y = 2
    c.z = 3
    del c.x
    del c.y
    assert c.z == 3
    with assertRaises(AttributeError, "attribute 'x' of 'C' undefined"):
        c.x
    with assertRaises(AttributeError, "attribute 'y' of 'C' undefined"):
        c.y

def test_delete_any() -> None:
    c: Any = C()
    c.x = 1
    c.y = 2
    c.z = 3
    del c.x
    del c.y
    with assertRaises(AttributeError, "'C' object attribute 'z' cannot be deleted"):
        del c.z
    assert c.z == 3
    with assertRaises(AttributeError):
        c.x
    with assertRaises(AttributeError):
        c.y

class Base:
    __deletable__ = ['a']
    a: int
    b: int

class Deriv(Base):
    __deletable__ = ('c',)
    c: str
    d: str

def test_delete_with_inheritance() -> None:
    d = Deriv()
    d.a = 0
    d.b = 1
    d.c = 'X'
    d.d = 'Y'
    del d.a
    with assertRaises(AttributeError):
        d.a
    del d.c
    with assertRaises(AttributeError):
        d.c
    assert d.b == 1
    assert d.d == 'Y'

def test_delete_with_inheritance_any() -> None:
    d: Any = Deriv()
    d.a = 0
    d.b = 1
    d.c = 'X'
    d.d = 'Y'
    del d.a
    with assertRaises(AttributeError):
        d.a
    del d.c
    with assertRaises(AttributeError):
        d.c
    with assertRaises(AttributeError):
        del d.b
    assert d.b == 1
    with assertRaises(AttributeError):
        del d.d
    assert d.d == 'Y'

def decorator(cls):
    return cls

@decorator
class NonExt:
    x: int
    y: int

    # No effect in a non-native class
    __deletable__ = ['x']

def test_non_ext() -> None:
    n = NonExt()
    n.x = 2
    n.y = 3
    del n.x
    del n.y
    with assertRaises(AttributeError):
        n.x
    with assertRaises(AttributeError):
        n.y

def test_non_ext_any() -> None:
    n: Any = NonExt()
    n.x = 2
    n.y = 3
    del n.x
    del n.y
    with assertRaises(AttributeError):
        n.x
    with assertRaises(AttributeError):
        n.y

[case testNonExtMisc]
from typing import Any, overload

def decorator(cls) -> Any:
    return cls

@decorator
class C:
    def __init__(self) -> None:
        self.c = 3

    def get_c(self) -> int:
        return self.c

@decorator
class B(C):
    def __init__(self) -> None:
        super().__init__()
        self.b = 2

    def get_b(self) -> int:
        return self.b

@decorator
class A(B):
    def __init__(self) -> None:
        super().__init__()
        self.a = 1

    @classmethod
    def constant(cls) -> int:
        return 4

    def get_a(self) -> int:
        return self.a

@decorator
class Overload:
    @overload
    def get(self, index: int) -> int: ...

    @overload
    def get(self, index: str) -> str: ...

    def get(self, index: Any) -> Any:
        return index

def get(c: Overload, s: str) -> str:
    return c.get(s)

@decorator
class Var:
    x = 'xy'

def get_class_var() -> str:
    return Var.x

[file driver.py]
from native import A, Overload, get, get_class_var
a = A()
assert a.a == 1
assert a.b == 2
assert a.c == 3
assert a.get_a() == 1
assert a.get_b() == 2
assert a.get_c() == 3
assert A.constant() == 4

o = Overload()
assert get(o, "test") == "test"
assert o.get(20) == 20

assert get_class_var() == 'xy'

[case testEnum]
from enum import Enum

class TestEnum(Enum):
    _order_ = "a b"
    a : int = 1
    b : int = 2

    @classmethod
    def test(cls) -> int:
        return 3

assert TestEnum.test() == 3

import enum

class Pokemon(enum.Enum):
    magikarp = 1
    squirtle = 2
    slowbro = 3

assert Pokemon.magikarp.value == 1
assert Pokemon.squirtle.name == 'squirtle'

[file other.py]
# Force a multi-module test to make sure we can compile multi-file with
# non-extension classes

[file driver.py]
import sys
# "_order_" isn't supported in 3.5
if sys.version_info[:2] > (3, 5):
    from native import TestEnum
    assert TestEnum.a.name == 'a'
    assert TestEnum.a.value == 1
    assert TestEnum.b.name == 'b'
    assert TestEnum.b.value == 2

[case testGetAttribute]
class C:
    x: int
    y: int

def getx(c: C) -> int:
    return c.x

def gety(c: C) -> int:
    return c.y
[file driver.py]
from native import C, getx, gety
c = C()
c.x = 10**30
c.y = 10**30 + 1
print(getx(c))
print(gety(c))
[out]
1000000000000000000000000000000
1000000000000000000000000000001

[case testSetAttribute]
class C:
    x: int
    y: int

def setx(c: C, v: int) -> None:
    c.x = v

def sety(c: C, v: int) -> None:
    c.y = v
[file driver.py]
from native import C, setx, sety
c = C()
setx(c, 10**30)
sety(c, 10**30 + 1)
print(c.x)
print(c.y)
setx(c, 4)
sety(c, 5)
print(c.x, c.y)
setx(c, 10**30 + 2)
sety(c, 10**30 + 3)
print(c.x)
print(c.y)
[out]
1000000000000000000000000000000
1000000000000000000000000000001
4 5
1000000000000000000000000000002
1000000000000000000000000000003

[case testAttributeTypes]
from typing import List, Tuple
class C:
    a: List[int]
    b: bool
    c: C
    d: object
    e: int

def setattrs(o: C, a: List[int], b: bool, c: C) -> None:
    o.a = a
    o.b = b
    o.c = c

def getattrs(o: C) -> Tuple[List[int], bool, C]:
    return o.a, o.b, o.c
[file driver.py]
from native import C, setattrs, getattrs
from testutil import assertRaises

c1 = C()
c2 = C()
aa = [2]
setattrs(c1, aa, True, c2)
a, b, c = getattrs(c1)
assert a is aa
assert b is True
assert c is c2

o = object()
c1.d = o
assert c1.d is o

c3 = C()
with assertRaises(AttributeError, "attribute 'a' of 'C' undefined"):
    c3.a
with assertRaises(AttributeError, "attribute 'b' of 'C' undefined"):
    c3.b
with assertRaises(AttributeError, "attribute 'c' of 'C' undefined"):
    c3.c
with assertRaises(AttributeError, "attribute 'd' of 'C' undefined"):
    c3.d
with assertRaises(AttributeError, "attribute 'e' of 'C' undefined"):
    c3.e

[case testInitMethodWithMissingNoneReturnAnnotation]
class C:
    def __init__(self):
        self.x = 42
[file driver.py]
from native import C
c = C()
assert c is not None
assert c.x == 42

[case testConstructClassWithDefaultConstructor]
class C:
    a: int
    b: int

def f() -> C:
    c = C()
    c.a = 13
    return c
[file driver.py]
from native import f, C
c = f()
assert c.a == 13
assert type(c) == C
assert not hasattr(c, 'b')

[case testCastUserClass]
from typing import List

class C:
    x: int

def f(a: List[C]) -> C:
    return a[0]
[file driver.py]
from native import f, C
c = C()
assert f([c]) is c

[case testClass1]
class A:
    def __init__(self, x: int) -> None:
        self.x = x
    def foo(self) -> int:
        return self.x+1
def foo() -> int:
    a = A(20)
    return a.foo()
[file driver.py]
from native import A, foo
a = A(10)
assert a.foo() == 11
assert foo() == 21

[case testGenericClass]
from typing import TypeVar, Generic, Sequence
T = TypeVar('T')
class C(Generic[T]):
    x: T
    def __init__(self, x: T) -> None:
        self.x = x
    def get(self) -> T:
        return self.x
    def set(self, y: T) -> None:
        self.x = y

# Test subclassing generic classes both with and without a generic param
class A(Sequence[int]):
    pass
class B(Sequence[T]):
    pass

def f(c: C[int]) -> int:
    y = c.get()
    d = C[int](2)
    c.set(c.get() + 1 + d.get())
    c.x = c.x + 2
    return c.x

[file driver.py]
from native import C, f
c = C(6)
assert f(c) == 11
c.x = 'x'
assert c.x == 'x'
c.set([1])
assert c.x == [1]
assert c.get() == [1]

[case testSubclass1]
from typing import Tuple

class A:
    def __init__(self) -> None:
        self.x = 10
    def hi(self, suffix: str) -> str:
        return str(self.x) + suffix
class B(A):
    def __init__(self) -> None:
        self.x = 20
        self.y = 'world'
    def hi(self, suffix: str) -> str:
        return 'hello ' + str(self.y) + suffix

def use_a(x: A) -> Tuple[int, str]:
    return (x.x, x.hi(''))
def use_b(x: B) -> str:
    return x.hi('')

[file driver.py]
from native import A, B, use_a, use_b
a = A()
b = B()
assert use_a(a) == (10, '10')
assert use_a(b) == (20, 'hello world')
assert a.x == 10
assert b.x == 20
assert b.y == 'world'
assert a.hi('!') == '10!'
assert b.hi('!') == 'hello world!'
assert use_b(b) == 'hello world'

[case testSubclassSpecialize1]
class A:
    def foo(self, x: int) -> object:
        print('A')
        return str(x)
    def bar(self, x: int) -> None:
        print(x + 1)
class B(A):
    def foo(self, x: object) -> int:
        print('B')
        return id(x)
    def bar(self, x: object) -> None:
        print(x)

def use_a(x: A, y: int) -> object:
    x.bar(10)
    return x.foo(y)

def use_b(x: B, y: object) -> int:
    return x.foo(y)

[file driver.py]
from native import A, B, use_a, use_b
a = A()
b = B()
o = object()
i = 10
assert a.foo(10) == '10'
assert b.foo(o) == id(o)
assert use_a(a, 10) == '10'
assert use_b(b, o) == id(o)
assert use_a(b, i) == id(i)
[out]
A
B
11
A
B
10
B

[case testSubclassSpecialize2]
class A:
    def foo(self, x: int) -> object:
        print('A')
        return str(x)
class B(A):
    def foo(self, x: object) -> object:
        print('B')
        return x
class C(B):
    def foo(self, x: object) -> int:
        print('C')
        return id(x)

def use_a(x: A, y: int) -> object:
    return x.foo(y)

def use_b(x: B, y: object) -> object:
    return x.foo(y)

def use_c(x: C, y: object) -> int:
    return x.foo(y)

[file driver.py]
from native import A, B, C, use_a, use_b, use_c
a = A()
b = B()
c = C()
o = object()
i = 10
assert a.foo(10) == '10'
assert b.foo(o) == o
assert c.foo(o) == id(o)
assert use_a(a, 10) == '10'
assert use_a(b, i) is i
assert use_a(c, i) == id(i)
assert use_b(b, o) == o
assert use_b(c, o) == id(o)
assert use_c(c, o) == id(o)
[out]
A
B
C
A
B
C
B
C
C

[case testIsInstance]
from typing import Optional
class X: pass
class A(X): pass
class B(A): pass

def isa(x: object) -> bool:
    return isinstance(x, A)
def isint(x: object) -> bool:
    return isinstance(x, int)
def isstr(x: object) -> bool:
    return isinstance(x, str)
def islist(x: object) -> bool:
    return isinstance(x, list)
def ist(x: object, t: object) -> bool:  # TODO: Second argument should be 'type'
    return isinstance(x, t)
def pointless(x: Optional[X]) -> str:
    if isinstance(x, A):
        return str(x)
    return ''
[file driver.py]
from native import X, A, B, isa, isint, isstr, islist, ist
assert isa(1) == False
assert isa(A()) == True
assert isa(B()) == True
assert isa(X()) == False

assert isint(1) == True
assert isint('') == False
assert isint(A()) == False

assert isstr(1) == False
assert isstr('') == True

assert islist(1) == False
assert islist([]) == True

assert ist(1, int) == True
assert ist(1, str) == False
try:
    ist(1, 2)
except TypeError:
    pass
else:
    assert False

[case testSubclassUninitAttr]
class X:
    x: int
class A(X):
    pass
[file driver.py]
import traceback
from native import A
try:
    A().x
except AttributeError:
    traceback.print_exc()
[out]
Traceback (most recent call last):
  File "driver.py", line 4, in <module>
    A().x
AttributeError: attribute 'x' of 'X' undefined

[case testClassMethods]
from typing import ClassVar, Any
from typing_extensions import final
from mypy_extensions import mypyc_attr

from interp import make_interpreted_subclass

class C:
    lurr: ClassVar[int] = 9
    @staticmethod
    def foo(x: int) -> int:
        return 10 + x
    @classmethod
    def bar(cls, x: int) -> int:
        return cls.lurr + x
    @staticmethod
    def baz(x: int, y: int = 10) -> int:
        return y - x
    @classmethod
    def quux(cls, x: int, y: int = 10) -> int:
        return y - x
    @classmethod
    def call_other(cls, x: int) -> int:
        return cls.quux(x, 3)

class D(C):
    def f(self) -> int:
        return super().foo(1) + super().bar(2) + super().baz(10) + super().quux(10)

def ctest1() -> int:
    return C.foo(1) + C.bar(2) + C.baz(10) + C.quux(10) + C.quux(y=10, x=9)

def ctest2() -> int:
    c = C()
    return c.foo(1) + c.bar(2) + c.baz(10)

CAny: Any = C

def test_classmethod_using_any() -> None:
    assert CAny.foo(10) == 20
    assert CAny.bar(10) == 19

def test_classmethod_on_instance() -> None:
    c = C()
    assert c.foo(10) == 20
    assert c.bar(10) == 19
    assert c.call_other(1) == 2

def test_classmethod_misc() -> None:
    assert ctest1() == 23
    assert ctest2() == 22
    assert C.call_other(2) == 1

def test_classmethod_using_super() -> None:
    d = D()
    assert d.f() == 22

@final
class F1:
    @classmethod
    def f(cls, x: int) -> int:
        return cls.g(x)

    @classmethod
    def g(cls, x: int) -> int:
        return x + 1

class F2:  # Implicitly final (no subclasses)
    @classmethod
    def f(cls, x: int) -> int:
        return cls.g(x)

    @classmethod
    def g(cls, x: int) -> int:
        return x + 1

def test_classmethod_of_final_class() -> None:
    assert F1.f(5) == 6
    assert F2.f(7) == 8

@mypyc_attr(allow_interpreted_subclasses=True)
class CI:
    @classmethod
    def f(cls, x: int) -> int:
        return cls.g(x)

    @classmethod
    def g(cls, x: int) -> int:
        return x + 1

def test_classmethod_with_allow_interpreted() -> None:
    assert CI.f(4) == 5
    sub = make_interpreted_subclass(CI)
    assert sub.f(4) == 7

[file interp.py]
def make_interpreted_subclass(base):
    class Sub(base):
        @classmethod
        def g(cls, x: int) -> int:
            return x + 3
    return Sub

[case testSuper]
from mypy_extensions import trait
from typing import List

class A:
    def __init__(self, x: int) -> None:
        self.x = x

    def foo(self, x: int) -> int:
        return x

class B(A):
    def __init__(self, x: int, y: int) -> None:
        super().__init__(x)
        self.y = y

    def foo(self, x: int) -> int:
        return super().foo(x+1)

class C(B):
    def __init__(self, x: int, y: int) -> None:
        super(C, self).__init__(x, y + 1)

    def foo(self, x: int) -> int:
        # should go to A, not B
        return super(B, self).foo(x+1)

class X:
    def __init__(self, x: int) -> None:
        self.x = x
class Y(X):
    pass
class Z(Y):
    def __init__(self, x: int, y: int) -> None:
        super().__init__(x)
        self.y = y

@trait
class T:
    def v_int(self, x: int) -> None: pass
    def v_list(self, x: List[int]) -> None:
        if x:
            self.v_int(x[0])
            self.v_list(x[1:])

class PrintList(T):
    def v_int(self, x: int) -> None:
        print(x)
    def v_list(self, x: List[int]) -> None:
        print('yo!')
        super().v_list(x)

[file driver.py]
import traceback
from native import *
b = B(10, 20)
assert b.x == 10 and b.y == 20
c = C(10, 20)
assert c.x == 10 and c.y == 21
z = Z(10, 20)
assert z.x == 10 and z.y == 20

assert c.foo(10) == 11

PrintList().v_list([1,2,3])
[out]
yo!
1
yo!
2
yo!
3
yo!

[case testSubclassException]
class Failure(Exception):
    def __init__(self, x: int) -> None:
        self.x = x

def foo() -> None:
    raise Failure(10)

def heyo() -> int:
    try:
        foo()
    except Failure as e:
        return e.x
    return -1

[file driver.py]
from native import foo, heyo, Failure
try:
    foo()
except Failure as e:
    assert str(e) == '10'
    assert e.x == 10
heyo()

[case testSubclassDict]
from typing import Dict
class WelpDict(Dict[str, int]):
    def __init__(self) -> None:
        self.emarhavil = 3
    def foo(self) -> int:
        return self.emarhavil

def welp() -> int:
    x = WelpDict()
    x['a'] = 10
    x['b'] = 15
    x.emarhavil = 5
    return x['a'] + x['b'] + x.emarhavil + x.foo()

[file driver.py]
from native import welp
assert welp() == 35

[case testSubclassPy]
from b import B, V
class A(B):
    def __init__(self, x: int, y: int) -> None:
        super().__init__(y)
        self.x = x

    def foo(self, x: int) -> int:
        print("hi", x)
        return x+1

class C(V[int]):
    def f(self) -> int: return 10

assert isinstance(C(), V)

def f(x: A) -> None:
    print(x.x)
    print(x.y)
    print(x.foo(20))

[file b.py]
from typing import Generic, TypeVar
T = TypeVar('T')

class B:
    def __init__(self, y: int) -> None:
        self.y = y
    def foo(self, x: int) -> int:
        print("parent!")
        return x + self.y
    def bar(self) -> None:
        print("hello!", self.y)

class V(Generic[T]):
    def f(self) -> T:
        raise Exception('unimplemented')
[file driver.py]
import native
a = native.A(10, 20)
a.foo(10)
a.bar()
native.f(a)
[out]
hi 10
hello! 20
10
20
hi 20
21

[case testDisallowSubclassFromPy]
# We'll want to allow this at some point but right now we need to
# disallow it because it doesn't work.
class A:
    pass
[file b.py]
from native import A

# It would be better if we disallowed it at class decl time but it is
# really easy to do in __new__

class B(A):
    pass

[file driver.py]
from b import B
try:
    B()
except TypeError:
    pass
else:
    assert False, "instantiating was supposed to fail"

[case testClassVariable]
MYPY = False
if MYPY:
    from typing import ClassVar
class A:
    x = 10  # type: ClassVar[int]

def g(x: int) -> None:
    A.x = 10
def f() -> int:
    return A.x
[file driver.py]
from native import A, f
assert f() == 10
A.x = 200
assert f() == 200

[case testDefaultVars]
from typing import Optional
class A:
    x = 10
    w: object = 10
    def lol(self) -> None:
        self.x = 100

LOL = 'lol'
class B(A):
    y = LOL
    z = None  # type: Optional[str]
    b = True
    bogus = None  # type: int

def g() -> None:
    a = A()
    assert a.x == 10
    a.x = 20
    assert a.x == 20
    b = B()
    assert b.x == 10
    b.x = 20
    assert b.x == 20
    assert b.y == 'lol'
    b.y = 'rofl'
    assert b.y == 'rofl'
    assert b.z is None
[file driver.py]
from native import *
g()

a = A()
assert a.x == 10
a.x = 20
assert a.x == 20
b = B()
assert b.x == 10
b.x = 20
assert b.x == 20
assert b.y == 'lol'
b.y = 'rofl'
assert b.y == 'rofl'
assert b.z is None
# N.B: this doesn't match cpython
assert not hasattr(b, 'bogus')

[case testProtocol]
from typing_extensions import Protocol

class Proto(Protocol):
    def foo(self, x: int) -> None:
        pass

    def bar(self, x: int) -> None:
        pass

class A:
    def foo(self, x: int) -> None:
        print("A:", x)

    def bar(self, *args: int, **kwargs: int) -> None:
        print("A:", args, kwargs)

class B(A, Proto):
    def foo(self, x: int) -> None:
        print("B:", x)

    def bar(self, *args: int, **kwargs: int) -> None:
        print("B:", args, kwargs)

def f(x: Proto) -> None:
    x.foo(20)
    x.bar(x=20)

[file driver.py]
from native import A, B, f

f(A())
f(B())

# ... this exploits a bug in glue methods to distinguish whether we
# are making a direct call or a pycall...
[out]
A: 20
A: () {'x': 20}
B: 20
B: (20,) {}

[case testMethodOverrideDefault1]
class A:
    def foo(self, x: int) -> None:
        pass
class B(A):
    def foo(self, x: int, y: int = 10) -> None:
        print(x, y)

def a(x: A) -> None:
    x.foo(1)
def b(x: B) -> None:
    x.foo(2)
    x.foo(2, 3)

[file driver.py]
from native import B, a, b
a(B())
b(B())
[out]
1 10
2 10
2 3

[case testMethodOverrideDefault2]
class A:
    def foo(self, *, x: int = -1) -> None:
        pass
    def bar(self, *, x: int = -1, y: int = -1) -> None:
        pass
    def baz(self, x: int = -1) -> None:
        pass
class B(A):
    def foo(self, *, y: int = 0, x: int = 0) -> None:
        print(x, y)
    def bar(self, *, y: int = 0, x: int = 0) -> None:
        print(x, y)
    def baz(self, x: int = 0, *, y: int = 0) -> None:
        print(x, y)

def a(x: A) -> None:
    x.foo(x=1)
    x.bar(x=1, y=2)
    x.bar(x=2, y=1)
    x.baz()
    x.baz(1)
    x.baz(x=2)

[file driver.py]
from native import B, a
a(B())
[out]
1 0
1 2
2 1
0 0
1 0
2 0

[case testMethodOverrideDefault3]
class A:
    @classmethod
    def foo(cls, *, x: int = 0) -> None:
        pass
    @staticmethod
    def bar(*, x: int = 0) -> None:
        pass
    @staticmethod
    def baz() -> object:
        pass
class B(A):
    @classmethod
    def foo(cls, *, y: int = 0, x: int = 0) -> None:
        print(x, y)
        print(cls.__name__)  # type: ignore
    @staticmethod
    def bar(*, y: int = 0, x: int = 0) -> None:
        print(x, y)
    @staticmethod
    def baz() -> int:
        return 10

# This is just to make sure that this stuff works even when the
# methods might be overridden.
class C(B):
    @classmethod
    def foo(cls, *, y: int = 0, x: int = 0) -> None:
        pass
    @staticmethod
    def bar(*, y: int = 0, x: int = 0) -> None:
        pass
    @staticmethod
    def baz() -> int:
        return 10

def a(x: A) -> None:
    x.foo(x=1)
    x.bar(x=1)
    print(x.baz())

[file driver.py]
from native import B, a
a(B())
[out]
1 0
B
1 0
10

[case testMethodOverrideDefault4]
class Foo:
    def f(self, x: int=20, *, z: int=10) -> None:
        pass

class Bar(Foo):
    def f(self, *args: int, **kwargs: int) -> None:
        print("stuff", args, kwargs)

z: Foo = Bar()
z.f(1, z=50)
z.f()

[out]
stuff (1,) {'z': 50}
stuff () {}

[case testMethodOverrideDefault5]
from testutil import make_python_function
from mypy_extensions import mypyc_attr
from typing import TypeVar, Any

@mypyc_attr(allow_interpreted_subclasses=True)
class Foo:
    def f(self, x: int=20, *, z: int=10) -> None:
        print("Foo", x, z)

@make_python_function
def baz_f(self: Any, *args: int, **kwargs: int) -> None:
    print("Baz", args, kwargs)

# Make an "interpreted" subtype of Foo
type2: Any = type
Bar = type2('Bar', (Foo,), {})
Baz = type2('Baz', (Foo,), {'f': baz_f})

y: Foo = Bar()
y.f(1, z=2)
y.f()

z: Foo = Baz()
z.f(1, z=2)
z.f()

[out]
Foo 1 2
Foo 20 10
Baz (1,) {'z': 2}
Baz () {}

[case testMethodOverrideDefault6]
from typing import Optional

class Foo:
    def f(self, x: int=20) -> None:
        pass

class Bar(Foo):
    def f(self, x: Optional[int]=None) -> None:
        print(x)

z: Foo = Bar()
z.f(1)
z.f()

[out]
1
None

[case testMethodOverrideDefault7]
from typing import TypeVar, Any

class Foo:
    def f(self, x: int, *args: int, **kwargs: int) -> None:
        print("Foo", x, args, kwargs)

class Bar(Foo):
    def f(self, *args: int, **kwargs: int) -> None:
        print("Bar", args, kwargs)

z: Foo = Bar()
z.f(1, z=2)
z.f(1, 2, 3)
# z.f(x=5)  # Not tested because we (knowingly) do the wrong thing and pass it as positional

[out]
Bar (1,) {'z': 2}
Bar (1, 2, 3) {}
--Bar () {'x': 5}

[case testMethodOverrideDefault8]
from typing import TypeVar, Any

class Foo:
    def f(self, *args: int, **kwargs: int) -> None:
        print("Foo", args, kwargs)

class Bar(Foo):
    def f(self, x: int = 10, *args: int, **kwargs: int) -> None:
        print("Bar", x, args, kwargs)

z: Foo = Bar()
z.f(1, z=2)
z.f(1, 2, 3)
z.f()

[out]
Bar 1 () {'z': 2}
Bar 1 (2, 3) {}
Bar 10 () {}

[case testMethodOverrideDefault9]
from testutil import make_python_function
from mypy_extensions import mypyc_attr
from typing import TypeVar, Any

@mypyc_attr(allow_interpreted_subclasses=True)
class Foo:
    def f(self, x: int=20, y: int=40) -> None:
        print("Foo", x, y)

# This sort of argument renaming is dodgy and not really sound but we
# shouldn't break it when they aren't actually used by name...
# (They *ought* to be positional only!)
@make_python_function
def baz_f(self, a: int=30, y: int=50) -> None:
    print("Baz", a, y)

# Make an "interpreted" subtype of Foo
type2: Any = type
Baz = type2('Baz', (Foo,), {'f': baz_f})

z: Foo = Baz()
z.f()
z.f(y=1)
z.f(1, 2)
# Not tested because we don't (and probably won't) match cpython here
# from testutil import assertRaises
# with assertRaises(TypeError):
#     z.f(x=7)

[out]
Baz 30 50
Baz 30 1
Baz 1 2

[case testOverride]
class A:
    def f(self) -> int:
        return 0
    def g(self) -> int:
        return 1

class B(A):
    def g(self) -> int:
        return 2

class C(B):
    def f(self) -> int:
        return 3

def test() -> None:
    ba: A = B()
    ca: A = C()
    assert ba.f() == 0
    assert ba.g() == 2
    assert ca.f() == 3
    assert ca.g() == 2
    cc = C()
    assert cc.f() == 3
    assert cc.g() == 2
    print('ok')
[file driver.py]
import native
native.test()
[out]
ok

[case testNoMetaclass]
from foo import Base

class Nothing(Base):  # type: ignore
    pass

[file foo.py]
from typing import Any
class Meta(type):
    pass

class _Base(metaclass=Meta):
    pass
Base = _Base  # type: Any

[file driver.py]
try:
    import native
except TypeError as e:
    assert(str(e) == "mypyc classes can't have a metaclass")

[case testMetaclass]
from meta import Meta

class Nothing(metaclass=Meta):
    pass

def ident(x): return x

@ident
class Test:
    pass

[file meta.py]
class Meta(type):
    def __new__(mcs, name, bases, dct):
        dct['X'] = 10
        return super().__new__(mcs, name, bases, dct)


[file driver.py]
from native import Nothing
assert Nothing.X == 10

[case testPickling]
from mypy_extensions import trait, mypyc_attr
from typing import Any, TypeVar, Generic

def dec(x: Any) -> Any:
    return x

@mypyc_attr(allow_interpreted_subclasses=True)
class A:
    x: int
    y: str

@mypyc_attr(allow_interpreted_subclasses=True)
class B(A):
    z: bool

    def __init__(self, x: int, y: str, z: bool) -> None:
        self.x = x
        self.y = y
        self.z = z

@trait
class T:
    a: str

class C(B, T):
    w: object

    # property shouldn't go in
    @property
    def foo(self) -> int:
        return 0

@dec
class D:
    x: int

class E(D):
    y: int


U = TypeVar('U')

class F(Generic[U]):
    y: int

class G(F[int]):
    pass

[file driver.py]
from native import A, B, T, C, D, E, F, G

import copy
import pickle

assert A.__mypyc_attrs__ == ('x', 'y')
assert B.__mypyc_attrs__ == ('z', 'x', 'y')
assert T.__mypyc_attrs__ == ('a',)
assert C.__mypyc_attrs__ == ('w', 'z', 'x', 'y', 'a')
assert not hasattr(D, '__mypyc_attrs__')
assert E.__mypyc_attrs__ == ('y', '__dict__')
assert F.__mypyc_attrs__ == ('y', '__dict__')
assert G.__mypyc_attrs__ == ('y', '__dict__')

b = B(10, '20', False)
assert b.__getstate__() == {'z': False, 'x': 10, 'y': '20'}
b2 = copy.copy(b)
assert b is not b2 and b.y == b2.y

b3 = pickle.loads(pickle.dumps(b))
assert b is not b3 and b.y == b3.y

e = E()
e.x = 10
e.y = 20

assert e.__getstate__() == {'y': 20, '__dict__': {'x': 10}}
e2 = pickle.loads(pickle.dumps(e))
assert e is not e2 and e.x == e2.x and e.y == e2.y


[case testInterpretedParentInit]
from interp import C
from typing import TypeVar

T = TypeVar('T')

def dec(x: T) -> T:
    return x

@dec
class A:
    def __init__(self, x: int) -> None:
        self.x = x

class B(A):
    s = 'test'

def b(x: int) -> B: return B(x)

class D(C):
    s = 'test'

def d(x: int) -> D: return D(x)


[file interp.py]
class C:
    def __init__(self, x: int) -> None:
        self.x = x

[file driver.py]
from native import b, d, B, D

def test(f, v):
    x = f(v)
    assert x.x == v
    assert x.s == 'test'

test(b, 20)
test(d, 30)
test(B, -1)
test(D, -2)

[case testInterpretedInherit]
from typing import TypeVar, Any, overload
from mypy_extensions import mypyc_attr, trait

T = TypeVar('T')
def dec(x: T) -> T: return x

@mypyc_attr(allow_interpreted_subclasses=True)
class Top:
    def spam(self) -> str:
        return "grandparent"

@mypyc_attr(allow_interpreted_subclasses=True)
@trait
class Trait:
    def trait_method(self) -> str:
        return "trait"

@mypyc_attr(allow_interpreted_subclasses=True)
class Foo(Top, Trait):
    def __init__(self, x: int) -> None:
        self.x = x

    def foo(self) -> str:
        return "parent foo: " + self.bar(self.x)

    def bar(self, x: int) -> str:
        return "parent bar: {}".format(x + self.x)

    @dec
    def decorated(self) -> str:
        return "decorated parent"

    @property
    def read_property(self) -> str:
        return "parent prop"

    @overload
    def overloaded(self, index: int) -> int: ...

    @overload
    def overloaded(self, index: str) -> str: ...

    def overloaded(self, index: Any) -> Any:
        return index

def foo(x: Foo) -> str:
    return x.foo()

def bar(x: Foo, y: int) -> str:
    return x.bar(y)

def spam(x: Top) -> str:
    return x.spam()

def decorated(x: Foo) -> str:
    return x.decorated()

def prop(x: Foo) -> str:
    return x.read_property

def trait_method(x: Trait) -> str:
    return x.trait_method()

def overloaded(x: Foo, s: str) -> str:
    return x.overloaded(s)

[file interp.py]
from typing import Any
from native import Foo

class Bar(Foo):
    def bar(self, x: int) -> str:
        return "child bar: {}".format(x + self.x)

    def spam(self) -> str:
        assert super().spam() == "grandparent"
        return "child"

    @property
    def read_property(self) -> str:
        return "child prop"

    def decorated(self) -> str:
        return "decorated child"

    def trait_method(self) -> str:
        return "child"

    def overloaded(self, index: Any) -> Any:
        return index + index


class InterpBase:
    def eggs(self) -> str:
        return "eggs"

class Baz(InterpBase, Bar):
    def __init__(self) -> None:
        super().__init__(1000)
        self.z = self.read_property

[file driver.py]
from native import Foo, foo, bar, spam, decorated, overloaded, prop, trait_method
from interp import Bar, Baz
from unittest.mock import patch
from testutil import assertRaises

x = Foo(10)
y = Bar(20)
z = Baz()

assert isinstance(y, Bar)
assert y.x == 20
assert y.bar(10) == "child bar: 30"
assert y.foo() == "parent foo: child bar: 40"
assert foo(y) == "parent foo: child bar: 40"
assert bar(y, 30) == "child bar: 50"
y.x = 30
assert bar(y, 30) == "child bar: 60"

assert spam(y) == "child"
assert y.read_property == "child prop"
assert prop(x) == "parent prop"
assert prop(y) == "child prop"
assert y.decorated() == "decorated child"
assert decorated(y) == "decorated child"
assert y.overloaded("test") == "testtest"
assert overloaded(y, "test") == "testtest"

assert y.trait_method() == "child"
assert trait_method(y) == "child"

assert z.bar(10) == "child bar: 1010"
assert bar(z, 10) == "child bar: 1010"
assert z.z == "child prop"
assert z.eggs() == "eggs"

with patch("interp.Bar.spam", lambda self: "monkey patched"):
    assert y.spam() == "monkey patched"
    spam(y) == "monkey patched"

with patch("interp.Bar.spam", lambda self: 20):
    assert y.spam() == 20
    with assertRaises(TypeError, "str object expected; got int"):
        spam(y)

with assertRaises(TypeError, "int object expected; got str"):
    y.x = "test"

[case testProperty]
from typing import Callable
from mypy_extensions import trait
class Temperature:
    @property
    def celsius(self) -> float:
        return 5.0 * (self.fahrenheit - 32.0) / 9.0

    def __init__(self, fahrenheit: float) -> None:
        self.fahrenheit = fahrenheit

    def print_temp(self) -> None:
        print("F:", self.fahrenheit, "C:", self.celsius)

    @property
    def rankine(self) -> float:
        raise NotImplementedError

class Access:
    @property
    def number_of_accesses(self) -> int:
        self._count += 1
        return self._count
    def __init__(self) -> None:
        self._count = 0

from typing import Callable
class BaseProperty:
    @property
    def doc(self) -> str:
        return "Represents a sequence of values. Updates itself by next, which is a new value."

    @property
    def value(self) -> object:
        return self._incrementer

    @property
    def bad_value(self) -> object:
        return self._incrementer

    @property
    def next(self) -> BaseProperty:
        return BaseProperty(self._incrementer + 1)

    def __init__(self, value: int) -> None:
        self._incrementer = value

class DerivedProperty(BaseProperty):
    @property
    def value(self) -> int:
        return self._incrementer

    @property
    def bad_value(self) -> object:
        return self._incrementer

    def __init__(self, incr_func: Callable[[int], int], value: int) -> None:
        BaseProperty.__init__(self, value)
        self._incr_func = incr_func

    @property
    def next(self) -> DerivedProperty:
        return DerivedProperty(self._incr_func, self._incr_func(self.value))

class AgainProperty(DerivedProperty):
    @property
    def next(self) -> AgainProperty:
        return AgainProperty(self._incr_func, self._incr_func(self._incr_func(self.value)))

    @property
    def bad_value(self) -> int:
        return self._incrementer

def print_first_n(n: int, thing: BaseProperty) -> None:
    vals = []
    cur_thing = thing
    for _ in range(n):
        vals.append(cur_thing.value)
        cur_thing = cur_thing.next
    print ('', vals)

@trait
class Trait:
    @property
    def value(self) -> int:
        return 3

class Printer(Trait):
    def print_value(self) -> None:
        print(self.value)

[file driver.py]
from native import Temperature, Access
import traceback
x = Temperature(32.0)
try:
    print (x.rankine)
except NotImplementedError as e:
    traceback.print_exc()
print (x.celsius)
x.print_temp()

y = Temperature(212.0)
print (y.celsius)
y.print_temp()

z = Access()
print (z.number_of_accesses)
print (z.number_of_accesses)
print (z.number_of_accesses)
print (z.number_of_accesses)

from native import BaseProperty, DerivedProperty, AgainProperty, print_first_n
a = BaseProperty(7)
b = DerivedProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7)
c = AgainProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7)

def py_print_first_n(n: int, thing: BaseProperty) -> None:
    vals = []
    cur_thing = thing
    for _ in range(n):
        vals.append(cur_thing.value)
        cur_thing = cur_thing.next
    print ('', vals)

py_print_first_n(20, a)
py_print_first_n(20, b)
py_print_first_n(20, c)

print(a.next.next.next.bad_value)
print(b.next.next.next.bad_value)
print(c.next.next.next.bad_value)

print_first_n(20, a)
print_first_n(20, b)
print_first_n(20, c)

print (a.doc)
print (b.doc)
print (c.doc)

from native import Printer
Printer().print_value()
print (Printer().value)
[out]
Traceback (most recent call last):
  File "driver.py", line 5, in <module>
    print (x.rankine)
  File "native.py", line 16, in rankine
    raise NotImplementedError
NotImplementedError
0.0
F: 32.0 C: 0.0
100.0
F: 212.0 C: 100.0
1
2
3
4
 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
 [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
 [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
10
34
26
 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
 [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
 [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
3
3
[out version>=3.11]
Traceback (most recent call last):
  File "driver.py", line 5, in <module>
    print (x.rankine)
           ^^^^^^^^^
  File "native.py", line 16, in rankine
    raise NotImplementedError
NotImplementedError
0.0
F: 32.0 C: 0.0
100.0
F: 212.0 C: 100.0
1
2
3
4
 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
 [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
 [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
10
34
26
 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
 [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
 [7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
3
3

[case testPropertySetters]

from mypy_extensions import trait

class Foo():
    def __init__(self) -> None:
        self.attr = "unmodified"

class A:
    def __init__(self) -> None:
        self._x = 0
        self._foo = Foo()

    @property
    def x(self) -> int:
        return self._x

    @x.setter
    def x(self, val : int) -> None:
        self._x = val

    @property
    def foo(self) -> Foo:
        return self._foo

    @foo.setter
    def foo(self, val : Foo) -> None:
        self._foo = val

# Overrides base property setters and getters
class B(A):
    def __init__(self) -> None:
        self._x = 10

    @property
    def x(self) -> int:
        return self._x + 1

    @x.setter
    def x(self, val : int) -> None:
        self._x = val + 1

# Inherits base property setters and getters
class C(A):
    def __init__(self) -> None:
        A.__init__(self)

@trait
class D():
    def __init__(self) -> None:
        self._x = 0

    @property
    def x(self) -> int:
        return self._x

    @x.setter
    def x(self, val : int) -> None:
        self._x = val

#Inherits trait property setters and getters
class E(D):
    def __init__(self) -> None:
        D.__init__(self)

#Overrides trait property setters and getters
class F(D):
    def __init__(self) -> None:
        self._x = 10

    @property
    def x(self) -> int:
        return self._x + 10

    @x.setter
    def x(self, val : int) -> None:
        self._x = val + 10

# # Property setter and getter are subtypes of base property setters and getters
# # class G(A):
# #   def __init__(self) -> None:
# #       A.__init__(self)

# #   @property
# #   def y(self) -> int:
# #       return self._y

# #   @y.setter
# #   def y(self, val : object) -> None:
# #       self._y = val

# No inheritance, just plain setter/getter
class G:
    def __init__(self, x: int) -> None:
        self._x = x

    @property
    def x(self) -> int:
        return self._x

    @x.setter
    def x(self, x: int) -> None:
        self._x = x

class H:
    def __init__(self, g: G) -> None:
        self.g = g
        self.g.x = 5  # Should not be treated as initialization

[file other.py]
# Run in both interpreted and compiled mode

from native import A, B, C, D, E, F, G

a = A()
assert a.x == 0
assert a._x == 0
a.x = 1
assert a.x == 1
assert a._x == 1
a._x = 0
assert a.x == 0
assert a._x == 0
b = B()
assert b.x == 11
assert b._x == 10
b.x = 11
assert b.x == 13
b._x = 11
assert b.x == 12
c = C()
assert c.x == 0
c.x = 1000
assert c.x == 1000
e = E()
assert e.x == 0
e.x = 1000
assert e.x == 1000
f = F()
assert f.x == 20
f.x = 30
assert f.x == 50
g = G(4)
g.x = 20
assert g.x == 20

[file driver.py]
# Run the tests in both interpreted and compiled mode
import other
import other_interpreted

[out]

[case testAttributeOverridesProperty]
from typing import Any
from mypy_extensions import trait

@trait
class T1:
    @property
    def x(self) -> int: ...
    @property
    def y(self) -> int: ...

class C1(T1):
    x: int = 1
    y: int = 4

def test_read_only_property_in_trait_implemented_as_attribute() -> None:
    c = C1()
    c.x = 5
    assert c.x == 5
    assert c.y == 4
    c.y = 6
    assert c.y == 6
    t: T1 = C1()
    assert t.y == 4
    t = c
    assert t.x == 5
    assert t.y == 6
    a: Any = c
    assert a.x == 5
    assert a.y == 6
    a.x = 7
    a.y = 8
    assert a.x == 7
    assert a.y == 8

class B2:
    @property
    def x(self) -> int:
        return 11

    @property
    def y(self) -> int:
        return 25

class C2(B2):
    x: int = 1
    y: int = 4

def test_read_only_property_in_class_implemented_as_attribute() -> None:
    c = C2()
    c.x = 5
    assert c.x == 5
    assert c.y == 4
    c.y = 6
    assert c.y == 6
    b: B2 = C2()
    assert b.y == 4
    b = c
    assert b.x == 5
    assert b.y == 6
    a: Any = c
    assert a.x == 5
    assert a.y == 6
    a.x = 7
    a.y = 8
    assert a.x == 7
    assert a.y == 8

@trait
class T3:
    @property
    def x(self) -> int: ...
    @property
    def y(self) -> int: ...

class B3:
    x: int = 1
    y: int = 4

class C3(B3, T3):
    pass

def test_read_only_property_implemented_as_attribute_indirectly() -> None:
    c = C3()
    c.x = 5
    assert c.x == 5
    assert c.y == 4
    c.y = 6
    assert c.y == 6
    t: T3 = C3()
    assert t.y == 4
    t = c
    assert t.x == 5
    assert t.y == 6
    a: Any = c
    assert a.x == 5
    assert a.y == 6
    a.x = 7
    a.y = 8
    assert a.x == 7
    assert a.y == 8

@trait
class T4:
    @property
    def x(self) -> int: ...
    @x.setter
    def x(self, v1: int) -> None: ...

    @property
    def y(self) -> int: ...
    @y.setter
    def y(self, v2: int) -> None: ...

class C4(T4):
    x: int = 1
    y: int = 4

def test_read_write_property_implemented_as_attribute() -> None:
    c = C4()
    c.x = 5
    assert c.x == 5
    assert c.y == 4
    c.y = 6
    assert c.y == 6
    t: T4 = C4()
    assert t.y == 4
    t.x = 5
    assert t.x == 5
    t.y = 6
    assert t.y == 6
    a: Any = c
    assert a.x == 5
    assert a.y == 6
    a.x = 7
    a.y = 8
    assert a.x == 7
    assert a.y == 8

@trait
class T5:
    @property
    def x(self) -> int: ...
    @x.setter
    def x(self, v1: int) -> None: ...

    @property
    def y(self) -> int: ...
    @y.setter
    def y(self, v2: int) -> None: ...

class B5:
    x: int = 1
    y: int = 4

class BB5(B5):
    pass

class C5(BB5, T5):
    pass

def test_read_write_property_indirectly_implemented_as_attribute() -> None:
    c = C5()
    c.x = 5
    assert c.x == 5
    assert c.y == 4
    c.y = 6
    assert c.y == 6
    t: T5 = C5()
    assert t.y == 4
    t.x = 5
    assert t.x == 5
    t.y = 6
    assert t.y == 6
    a: Any = c
    assert a.x == 5
    assert a.y == 6
    a.x = 7
    a.y = 8
    assert a.x == 7
    assert a.y == 8

[case testSubclassAttributeAccess]
from mypy_extensions import trait

class A:
    v = 0

class B(A):
    v = 1

class C(B):
    v = 2

[file driver.py]
from native import A, B, C

a = A()
b = B()
c = C()

[case testCopyAlwaysDefinedAttributes]
import copy
from typing import Union

class A: pass

class C:
    def __init__(self, n: int = 0) -> None:
        self.n = n
        self.s = ""
        self.t = ("", 0)
        self.u: Union[str, bytes] = ''
        self.a = A()

def test_copy() -> None:
    c1 = C()
    c1.n = 1
    c1.s = "x"
    c2 = copy.copy(c1)
    assert c2.n == 1
    assert c2.s == "x"
    assert c2.t == ("", 0)
    assert c2.u == ''
    assert c2.a is c1.a

[case testNonNativeCallsToDunderNewAndInit]
from typing import Any
from testutil import assertRaises

count_c = 0

class C:
    def __init__(self) -> None:
        self.x = 'a'  # Always defined attribute
        global count_c
        count_c += 1

    def get(self) -> str:
        return self.x

def test_no_init_args() -> None:
    global count_c
    count_c = 0

    # Use Any to get non-native semantics
    cls: Any = C
    # __new__ implicitly calls __init__ for native classes
    obj = cls.__new__(cls)
    assert obj.get() == 'a'
    assert count_c == 1
    # Make sure we don't call __init__ twice
    obj2 = cls()
    assert obj2.get() == 'a'
    assert count_c == 2

count_d = 0

class D:
    def __init__(self, x: str) -> None:
        self.x = x  # Always defined attribute
        global count_d
        count_d += 1

    def get(self) -> str:
        return self.x

def test_init_arg() -> None:
    global count_d
    count_d = 0

    # Use Any to get non-native semantics
    cls: Any = D
    # __new__ implicitly calls __init__ for native classes
    obj = cls.__new__(cls, 'abc')
    assert obj.get() == 'abc'
    assert count_d == 1
    # Make sure we don't call __init__ twice
    obj2 = cls('x')
    assert obj2.get() == 'x'
    assert count_d == 2
    # Keyword args should work
    obj = cls.__new__(cls, x='abc')
    assert obj.get() == 'abc'
    assert count_d == 3

def test_invalid_init_args() -> None:
    # Use Any to get non-native semantics
    cls: Any = D
    with assertRaises(TypeError):
        cls()
    with assertRaises(TypeError):
        cls(y='x')
    with assertRaises(TypeError):
        cls(1)

[case testTryDeletingAlwaysDefinedAttribute]
from typing import Any
from testutil import assertRaises

class C:
    def __init__(self) -> None:
        self.x = 0

class D(C):
    pass

def test_try_deleting_always_defined_attr() -> None:
    c: Any = C()
    with assertRaises(AttributeError):
        del c.x
    d: Any = D()
    with assertRaises(AttributeError):
        del d.x

[case testAlwaysDefinedAttributeAndAllowInterpretedSubclasses]
from mypy_extensions import mypyc_attr

from m import define_interpreted_subclass

@mypyc_attr(allow_interpreted_subclasses=True)
class Base:
    x = 5
    y: int
    def __init__(self, s: str) -> None:
        self.s = s

class DerivedNative(Base):
    def __init__(self) -> None:
        super().__init__('x')
        self.z = 3

def test_native_subclass() -> None:
    o = DerivedNative()
    assert o.x == 5
    assert o.s == 'x'
    assert o.z == 3

def test_interpreted_subclass() -> None:
    define_interpreted_subclass(Base)

[file m.py]
from testutil import assertRaises

def define_interpreted_subclass(b):
    class DerivedInterpreted1(b):
        def __init__(self):
            # Don't call base class __init__
            pass
    d1 = DerivedInterpreted1()
    assert d1.x == 5
    with assertRaises(AttributeError):
        d1.y
    with assertRaises(AttributeError):
        d1.s
    with assertRaises(AttributeError):
        del d1.x

    class DerivedInterpreted1(b):
        def __init__(self):
            super().__init__('y')
    d2 = DerivedInterpreted1()
    assert d2.x == 5
    assert d2.s == 'y'
    with assertRaises(AttributeError):
        d2.y
    with assertRaises(AttributeError):
        del d2.x

[case testBaseClassSometimesDefinesAttribute]
class C:
    def __init__(self, b: bool) -> None:
        if b:
            self.x = [1]

class D(C):
    def __init__(self, b: bool) -> None:
        super().__init__(b)
        self.x = [2]

def test_base_class() -> None:
    c = C(True)
    assert c.x == [1]
    c = C(False)
    try:
        c.x
    except AttributeError:
        return
    assert False

def test_subclass() -> None:
    d = D(True)
    assert d.x == [2]
    d = D(False)
    assert d.x == [2]

[case testSerializableClass]
from mypy_extensions import mypyc_attr
from typing import Any
import copy
from testutil import assertRaises

@mypyc_attr(serializable=True)
class Base:
    def __init__(self, s: str) -> None:
        self.s = s

class Derived(Base):
    def __init__(self, s: str, n: int) -> None:
        super().__init__(s)
        self.n = n

def test_copy_base() -> None:
    o = Base('xyz')
    o2 = copy.copy(o)
    assert isinstance(o2, Base)
    assert o2 is not o
    assert o2.s == 'xyz'

def test_copy_derived() -> None:
    d = Derived('xyz', 5)
    d2 = copy.copy(d)
    assert isinstance(d2, Derived)
    assert d2 is not d
    assert d2.s == 'xyz'
    assert d2.n == 5

class NonSerializable:
    def __init__(self, s: str) -> None:
        self.s = s

@mypyc_attr(serializable=True)
class SerializableSub(NonSerializable):
    def __init__(self, s: str, n: int) -> None:
        super().__init__(s)
        self.n = n

def test_serializable_sub_class() -> None:
    n = NonSerializable('xyz')
    assert n.s == 'xyz'

    with assertRaises(TypeError):
        copy.copy(n)

    s = SerializableSub('foo', 6)
    s2 = copy.copy(s)
    assert s2 is not s
    assert s2.s == 'foo'
    assert s2.n == 6

def test_serializable_sub_class_call_new() -> None:
    t: Any = SerializableSub
    sub: SerializableSub = t.__new__(t)
    with assertRaises(AttributeError):
        sub.s
    with assertRaises(AttributeError):
        sub.n
    base: NonSerializable = sub
    with assertRaises(AttributeError):
        base.s

[case testClassWithInherited__call__]
class Base:
    def __call__(self) -> int:
        return 1

class Derived(Base):
    pass

assert Derived()() == 1

[case testClassWithFinalAttribute]
from typing_extensions import Final

class C:
    A: Final = -1
    a: Final = [A]

def test_final_attribute() -> None:
    assert C.A == -1
    assert C.a == [-1]
