Coverage for mlprodict/grammar/grammar_sklearn/grammar/api_extension.py: 100%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

33 statements  

1""" 

2@file 

3@brief Implements decorators to extend the API. 

4""" 

5 

6 

7class AutoAction: 

8 """ 

9 Extends the API to automatically look for exporters. 

10 """ 

11 

12 def _reset_cache(self): 

13 """ 

14 A same node may appear at different places in the graph. 

15 It means the output is used twice. However, we don't want to 

16 include the code to generate that same output twice. We cache it 

17 and keep some information about it. 

18 """ 

19 self._cache = None 

20 for child in self.children: 

21 child._reset_cache() 

22 

23 def export(self, lang="json", hook=None, result_name=None): 

24 """ 

25 Exports into any format. 

26 The method is looking for one method call 

27 '_export_<lang>' and calls it if found. 

28 

29 @param lang language 

30 @param hook tweaking parameters 

31 @param result_name the name of the result decided by the parent of this node 

32 @return depends on the language 

33 """ 

34 self._reset_cache() 

35 name = "_export_{0}".format(lang) 

36 if hasattr(self, name): 

37 try: 

38 return getattr(self, name)(hook=hook, result_name=result_name) 

39 except TypeError as e: # pragma: no cover 

40 raise TypeError( 

41 "Signature of '{0}' is wrong for type '{1}'".format(name, type(self))) from e 

42 else: 

43 raise NotImplementedError( # pragma: no cover 

44 "No conversion is implemented for lang='{0}' and type='{1}'".format( 

45 lang, type(self))) 

46 

47 @staticmethod 

48 def cache(func): 

49 """Caches the result of a function.""" 

50 

51 def func_wrapper(self, hook=None, result_name=None): 

52 """Wrapper to cache the result of a function.""" 

53 if self._cache is not None: 

54 c = self._cache.copy() 

55 c['cache'] = True 

56 return c 

57 else: 

58 ret = func(self, hook=hook, result_name=result_name) 

59 if not isinstance(ret, dict): 

60 raise TypeError( # pragma: no cover 

61 "A dictionary was expected not '{0}'.\nIssue with class '{1}'" 

62 "".format( 

63 type(ret), type(self))) 

64 self._cache = ret 

65 ret = ret.copy() 

66 ret['cache'] = False 

67 return ret 

68 return func_wrapper 

69 

70 

71class AutoType: 

72 """ 

73 Extends the API to automatically look for exporters. 

74 """ 

75 

76 def format_value(self, value, lang="json", hook=None): 

77 """ 

78 Exports into any format. 

79 The method is looking for one method call 

80 '_export_<lang>' and calls it if found. 

81 

82 @param value value to format 

83 @param lang language 

84 @param hook tweaking parameters 

85 @return depends on the language 

86 """ 

87 name = "_format_value_{0}".format(lang) 

88 if hasattr(self, name): 

89 try: 

90 return getattr(self, name)(value, hook=hook) 

91 except TypeError as e: 

92 raise TypeError( 

93 "Singature of '{0}' is wrong for type '{1}'".format(name, type(self))) from e 

94 else: 

95 raise NotImplementedError( 

96 "No formatting is implemented for lang='{0}' and type='{1}'".format( 

97 lang, type(self)))