Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scikit_learn-1.4.dev0-py3.8-linux-x86_64.egg/sklearn/utils/_available_if.py: 50%

22 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-12 06:31 +0000

1from functools import update_wrapper, wraps 

2from types import MethodType 

3 

4 

5class _AvailableIfDescriptor: 

6 """Implements a conditional property using the descriptor protocol. 

7 

8 Using this class to create a decorator will raise an ``AttributeError`` 

9 if check(self) returns a falsey value. Note that if check raises an error 

10 this will also result in hasattr returning false. 

11 

12 See https://docs.python.org/3/howto/descriptor.html for an explanation of 

13 descriptors. 

14 """ 

15 

16 def __init__(self, fn, check, attribute_name): 

17 self.fn = fn 

18 self.check = check 

19 self.attribute_name = attribute_name 

20 

21 # update the docstring of the descriptor 

22 update_wrapper(self, fn) 

23 

24 def __get__(self, obj, owner=None): 

25 attr_err = AttributeError( 

26 f"This {repr(owner.__name__)} has no attribute {repr(self.attribute_name)}" 

27 ) 

28 if obj is not None: 

29 # delegate only on instances, not the classes. 

30 # this is to allow access to the docstrings. 

31 if not self.check(obj): 

32 raise attr_err 

33 out = MethodType(self.fn, obj) 

34 

35 else: 

36 # This makes it possible to use the decorated method as an unbound method, 

37 # for instance when monkeypatching. 

38 @wraps(self.fn) 

39 def out(*args, **kwargs): 

40 if not self.check(args[0]): 

41 raise attr_err 

42 return self.fn(*args, **kwargs) 

43 

44 return out 

45 

46 

47def available_if(check): 

48 """An attribute that is available only if check returns a truthy value. 

49 

50 Parameters 

51 ---------- 

52 check : callable 

53 When passed the object with the decorated method, this should return 

54 a truthy value if the attribute is available, and either return False 

55 or raise an AttributeError if not available. 

56 

57 Returns 

58 ------- 

59 callable 

60 Callable makes the decorated method available if `check` returns 

61 a truthy value, otherwise the decorated method is unavailable. 

62 

63 Examples 

64 -------- 

65 >>> from sklearn.utils.metaestimators import available_if 

66 >>> class HelloIfEven: 

67 ... def __init__(self, x): 

68 ... self.x = x 

69 ... 

70 ... def _x_is_even(self): 

71 ... return self.x % 2 == 0 

72 ... 

73 ... @available_if(_x_is_even) 

74 ... def say_hello(self): 

75 ... print("Hello") 

76 ... 

77 >>> obj = HelloIfEven(1) 

78 >>> hasattr(obj, "say_hello") 

79 False 

80 >>> obj.x = 2 

81 >>> hasattr(obj, "say_hello") 

82 True 

83 >>> obj.say_hello() 

84 Hello 

85 """ 

86 return lambda fn: _AvailableIfDescriptor(fn, check, attribute_name=fn.__name__)