1*523fa7a6SAndroid Build Coastguard Worker# Copyright (c) Meta Platforms, Inc. and affiliates. 2*523fa7a6SAndroid Build Coastguard Worker# All rights reserved. 3*523fa7a6SAndroid Build Coastguard Worker# 4*523fa7a6SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the 5*523fa7a6SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree. 6*523fa7a6SAndroid Build Coastguard Worker 7*523fa7a6SAndroid Build Coastguard Worker# pyre-strict 8*523fa7a6SAndroid Build Coastguard Workerimport unittest 9*523fa7a6SAndroid Build Coastguard Workerimport warnings 10*523fa7a6SAndroid Build Coastguard Workerfrom typing import Any, Callable, Optional 11*523fa7a6SAndroid Build Coastguard Worker 12*523fa7a6SAndroid Build Coastguard Workerfrom executorch.exir._warnings import deprecated, experimental, ExperimentalWarning 13*523fa7a6SAndroid Build Coastguard Worker 14*523fa7a6SAndroid Build Coastguard Worker# 15*523fa7a6SAndroid Build Coastguard Worker# Classes 16*523fa7a6SAndroid Build Coastguard Worker# 17*523fa7a6SAndroid Build Coastguard Worker 18*523fa7a6SAndroid Build Coastguard Worker 19*523fa7a6SAndroid Build Coastguard Workerclass UndecoratedClass: 20*523fa7a6SAndroid Build Coastguard Worker pass 21*523fa7a6SAndroid Build Coastguard Worker 22*523fa7a6SAndroid Build Coastguard Worker 23*523fa7a6SAndroid Build Coastguard Worker@deprecated("DeprecatedClass message") 24*523fa7a6SAndroid Build Coastguard Workerclass DeprecatedClass: 25*523fa7a6SAndroid Build Coastguard Worker pass 26*523fa7a6SAndroid Build Coastguard Worker 27*523fa7a6SAndroid Build Coastguard Worker 28*523fa7a6SAndroid Build Coastguard Worker@experimental("ExperimentalClass message") 29*523fa7a6SAndroid Build Coastguard Workerclass ExperimentalClass: 30*523fa7a6SAndroid Build Coastguard Worker pass 31*523fa7a6SAndroid Build Coastguard Worker 32*523fa7a6SAndroid Build Coastguard Worker 33*523fa7a6SAndroid Build Coastguard Worker# 34*523fa7a6SAndroid Build Coastguard Worker# Functions 35*523fa7a6SAndroid Build Coastguard Worker# 36*523fa7a6SAndroid Build Coastguard Worker 37*523fa7a6SAndroid Build Coastguard Worker 38*523fa7a6SAndroid Build Coastguard Workerdef undecorated_function() -> None: 39*523fa7a6SAndroid Build Coastguard Worker pass 40*523fa7a6SAndroid Build Coastguard Worker 41*523fa7a6SAndroid Build Coastguard Worker 42*523fa7a6SAndroid Build Coastguard Worker@deprecated("deprecated_function message") 43*523fa7a6SAndroid Build Coastguard Workerdef deprecated_function() -> None: 44*523fa7a6SAndroid Build Coastguard Worker pass 45*523fa7a6SAndroid Build Coastguard Worker 46*523fa7a6SAndroid Build Coastguard Worker 47*523fa7a6SAndroid Build Coastguard Worker@experimental("experimental_function message") 48*523fa7a6SAndroid Build Coastguard Workerdef experimental_function() -> None: 49*523fa7a6SAndroid Build Coastguard Worker pass 50*523fa7a6SAndroid Build Coastguard Worker 51*523fa7a6SAndroid Build Coastguard Worker 52*523fa7a6SAndroid Build Coastguard Worker# 53*523fa7a6SAndroid Build Coastguard Worker# Methods 54*523fa7a6SAndroid Build Coastguard Worker# 55*523fa7a6SAndroid Build Coastguard Worker 56*523fa7a6SAndroid Build Coastguard Worker 57*523fa7a6SAndroid Build Coastguard Workerclass TestClass: 58*523fa7a6SAndroid Build Coastguard Worker def undecorated_method(self) -> None: 59*523fa7a6SAndroid Build Coastguard Worker pass 60*523fa7a6SAndroid Build Coastguard Worker 61*523fa7a6SAndroid Build Coastguard Worker @deprecated("deprecated_method message") 62*523fa7a6SAndroid Build Coastguard Worker def deprecated_method(self) -> None: 63*523fa7a6SAndroid Build Coastguard Worker pass 64*523fa7a6SAndroid Build Coastguard Worker 65*523fa7a6SAndroid Build Coastguard Worker @experimental("experimental_method message") 66*523fa7a6SAndroid Build Coastguard Worker def experimental_method(self) -> None: 67*523fa7a6SAndroid Build Coastguard Worker pass 68*523fa7a6SAndroid Build Coastguard Worker 69*523fa7a6SAndroid Build Coastguard Worker 70*523fa7a6SAndroid Build Coastguard Worker# NOTE: Variables and fields cannot be decorated. 71*523fa7a6SAndroid Build Coastguard Worker 72*523fa7a6SAndroid Build Coastguard Worker 73*523fa7a6SAndroid Build Coastguard Workerclass TestApiLifecycle(unittest.TestCase): 74*523fa7a6SAndroid Build Coastguard Worker 75*523fa7a6SAndroid Build Coastguard Worker def is_deprecated( 76*523fa7a6SAndroid Build Coastguard Worker self, 77*523fa7a6SAndroid Build Coastguard Worker callable: Callable[[], Any], # pyre-ignore[2]: Any type 78*523fa7a6SAndroid Build Coastguard Worker message: Optional[str] = None, 79*523fa7a6SAndroid Build Coastguard Worker ) -> bool: 80*523fa7a6SAndroid Build Coastguard Worker with warnings.catch_warnings(record=True) as w: 81*523fa7a6SAndroid Build Coastguard Worker # Cause all warnings to always be triggered. 82*523fa7a6SAndroid Build Coastguard Worker warnings.simplefilter("always") 83*523fa7a6SAndroid Build Coastguard Worker 84*523fa7a6SAndroid Build Coastguard Worker # Try to trigger a warning. 85*523fa7a6SAndroid Build Coastguard Worker callable() 86*523fa7a6SAndroid Build Coastguard Worker 87*523fa7a6SAndroid Build Coastguard Worker if not w: 88*523fa7a6SAndroid Build Coastguard Worker # No warnings were triggered. 89*523fa7a6SAndroid Build Coastguard Worker return False 90*523fa7a6SAndroid Build Coastguard Worker if not issubclass(w[-1].category, DeprecationWarning): 91*523fa7a6SAndroid Build Coastguard Worker # There was a warning, but it wasn't a DeprecationWarning. 92*523fa7a6SAndroid Build Coastguard Worker return False 93*523fa7a6SAndroid Build Coastguard Worker if issubclass(w[-1].category, ExperimentalWarning): 94*523fa7a6SAndroid Build Coastguard Worker # ExperimentalWarning is a subclass of DeprecationWarning. 95*523fa7a6SAndroid Build Coastguard Worker return False 96*523fa7a6SAndroid Build Coastguard Worker if message: 97*523fa7a6SAndroid Build Coastguard Worker return message in str(w[-1].message) 98*523fa7a6SAndroid Build Coastguard Worker return True 99*523fa7a6SAndroid Build Coastguard Worker 100*523fa7a6SAndroid Build Coastguard Worker def is_experimental( 101*523fa7a6SAndroid Build Coastguard Worker self, 102*523fa7a6SAndroid Build Coastguard Worker callable: Callable[[], Any], # pyre-ignore[2]: Any type 103*523fa7a6SAndroid Build Coastguard Worker message: Optional[str] = None, 104*523fa7a6SAndroid Build Coastguard Worker ) -> bool: 105*523fa7a6SAndroid Build Coastguard Worker with warnings.catch_warnings(record=True) as w: 106*523fa7a6SAndroid Build Coastguard Worker # Cause all warnings to always be triggered. 107*523fa7a6SAndroid Build Coastguard Worker warnings.simplefilter("always") 108*523fa7a6SAndroid Build Coastguard Worker 109*523fa7a6SAndroid Build Coastguard Worker # Try to trigger a warning. 110*523fa7a6SAndroid Build Coastguard Worker callable() 111*523fa7a6SAndroid Build Coastguard Worker 112*523fa7a6SAndroid Build Coastguard Worker if not w: 113*523fa7a6SAndroid Build Coastguard Worker # No warnings were triggered. 114*523fa7a6SAndroid Build Coastguard Worker return False 115*523fa7a6SAndroid Build Coastguard Worker if not issubclass(w[-1].category, ExperimentalWarning): 116*523fa7a6SAndroid Build Coastguard Worker # There was a warning, but it wasn't an ExperimentalWarning. 117*523fa7a6SAndroid Build Coastguard Worker return False 118*523fa7a6SAndroid Build Coastguard Worker if message: 119*523fa7a6SAndroid Build Coastguard Worker return message in str(w[-1].message) 120*523fa7a6SAndroid Build Coastguard Worker return True 121*523fa7a6SAndroid Build Coastguard Worker 122*523fa7a6SAndroid Build Coastguard Worker def test_undecorated_class(self) -> None: 123*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(UndecoratedClass)) 124*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(UndecoratedClass)) 125*523fa7a6SAndroid Build Coastguard Worker 126*523fa7a6SAndroid Build Coastguard Worker def test_deprecated_class(self) -> None: 127*523fa7a6SAndroid Build Coastguard Worker self.assertTrue(self.is_deprecated(DeprecatedClass, "DeprecatedClass message")) 128*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(DeprecatedClass)) 129*523fa7a6SAndroid Build Coastguard Worker 130*523fa7a6SAndroid Build Coastguard Worker def test_experimental_class(self) -> None: 131*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(ExperimentalClass)) 132*523fa7a6SAndroid Build Coastguard Worker self.assertTrue( 133*523fa7a6SAndroid Build Coastguard Worker self.is_experimental(ExperimentalClass, "ExperimentalClass message") 134*523fa7a6SAndroid Build Coastguard Worker ) 135*523fa7a6SAndroid Build Coastguard Worker 136*523fa7a6SAndroid Build Coastguard Worker def test_undecorated_function(self) -> None: 137*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(undecorated_function)) 138*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(undecorated_function)) 139*523fa7a6SAndroid Build Coastguard Worker 140*523fa7a6SAndroid Build Coastguard Worker def test_deprecated_function(self) -> None: 141*523fa7a6SAndroid Build Coastguard Worker self.assertTrue( 142*523fa7a6SAndroid Build Coastguard Worker self.is_deprecated(deprecated_function, "deprecated_function message") 143*523fa7a6SAndroid Build Coastguard Worker ) 144*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(deprecated_function)) 145*523fa7a6SAndroid Build Coastguard Worker 146*523fa7a6SAndroid Build Coastguard Worker def test_experimental_function(self) -> None: 147*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(experimental_function)) 148*523fa7a6SAndroid Build Coastguard Worker self.assertTrue( 149*523fa7a6SAndroid Build Coastguard Worker self.is_experimental(experimental_function, "experimental_function message") 150*523fa7a6SAndroid Build Coastguard Worker ) 151*523fa7a6SAndroid Build Coastguard Worker 152*523fa7a6SAndroid Build Coastguard Worker def test_undecorated_method(self) -> None: 153*523fa7a6SAndroid Build Coastguard Worker tc = TestClass() 154*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(tc.undecorated_method)) 155*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(tc.undecorated_method)) 156*523fa7a6SAndroid Build Coastguard Worker 157*523fa7a6SAndroid Build Coastguard Worker def test_deprecated_method(self) -> None: 158*523fa7a6SAndroid Build Coastguard Worker tc = TestClass() 159*523fa7a6SAndroid Build Coastguard Worker self.assertTrue( 160*523fa7a6SAndroid Build Coastguard Worker self.is_deprecated(tc.deprecated_method, "deprecated_method message") 161*523fa7a6SAndroid Build Coastguard Worker ) 162*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_experimental(tc.deprecated_method)) 163*523fa7a6SAndroid Build Coastguard Worker 164*523fa7a6SAndroid Build Coastguard Worker def test_experimental_method(self) -> None: 165*523fa7a6SAndroid Build Coastguard Worker tc = TestClass() 166*523fa7a6SAndroid Build Coastguard Worker self.assertFalse(self.is_deprecated(tc.experimental_method)) 167*523fa7a6SAndroid Build Coastguard Worker self.assertTrue( 168*523fa7a6SAndroid Build Coastguard Worker self.is_experimental(tc.experimental_method, "experimental_method message") 169*523fa7a6SAndroid Build Coastguard Worker ) 170