@@ -2887,3 +2887,66 @@ def test_function():
28872887 explicit_ext_inst = AnnotatedExtensionClass()
28882888 with assertRaises(AttributeError):
28892889 setattr(explicit_ext_inst, 'attr_instance', 6)
2890+
2891+ [case testMypycAttrNativeClassDunder]
2892+ from mypy_extensions import mypyc_attr
2893+ from typing import Generic, TypeVar
2894+
2895+ _T = TypeVar("_T")
2896+
2897+ @mypyc_attr(native_class=False)
2898+ class Bar(Generic[_T]):
2899+ # Note the lack of __deletable__
2900+ def __init__(self) -> None:
2901+ self.value: str = 'start'
2902+ def __get__(self, instance: _T, owner: type[_T] | None = None) -> str:
2903+ return self.value
2904+ def __set__(self, instance: _T, value: str) -> None:
2905+ self.value = value
2906+ def __delete__(self, instance: _T) -> None:
2907+ del self.value
2908+
2909+ @mypyc_attr(native_class=False)
2910+ class Foo(object):
2911+ bar: Bar = Bar()
2912+
2913+ [file driver.py]
2914+ import native
2915+
2916+ f = native.Foo()
2917+ assert(hasattr(f, 'bar'))
2918+ assert(f.bar == 'start')
2919+ f.bar = 'test'
2920+ assert(f.bar == 'test')
2921+ del f.bar
2922+ assert(not hasattr(f, 'bar'))
2923+
2924+ [case testMypycAttrNativeClassMeta]
2925+ from mypy_extensions import mypyc_attr
2926+ from typing import ClassVar, TypeVar
2927+
2928+ _T = TypeVar("_T")
2929+
2930+ @mypyc_attr(native_class=False)
2931+ class M(type):
2932+ count: ClassVar[int] = 0
2933+ def make(cls: type[_T]) -> _T:
2934+ M.count += 1
2935+ return cls()
2936+
2937+ # implicit native_class=False
2938+ # see testMypycAttrNativeClassMetaError for when trying to set it True
2939+ class A(metaclass=M):
2940+ pass
2941+
2942+ [file driver.py]
2943+ import native
2944+
2945+ a: native.A = native.A.make()
2946+ assert(native.A.count == 1)
2947+
2948+ class B(native.A):
2949+ pass
2950+
2951+ b: B = B.make()
2952+ assert(B.count == 2)
0 commit comments