1from ..plugin_registry import PluginRegistry 2from typing import Callable 3 4 5class TypedCallableRegistry(PluginRegistry[Callable[[int], int]]): 6 pass 7 8 9class GeneralCallableRegistry(PluginRegistry): 10 _global_settings = {"global_setting": None} 11 12 @property 13 def global_setting(self): 14 return self._global_settings["global_setting"] 15 16 @global_setting.setter 17 def global_setting(self, val): 18 self._global_settings["global_setting"] = val 19 20 21def test_plugin_registry(): 22 plugins = TypedCallableRegistry() 23 24 assert plugins.names() == [] 25 assert plugins.active == "" 26 assert plugins.get() is None 27 assert repr(plugins) == "TypedCallableRegistry(active='', registered=[])" 28 29 plugins.register("new_plugin", lambda x: x ** 2) 30 assert plugins.names() == ["new_plugin"] 31 assert plugins.active == "" 32 assert plugins.get() is None 33 assert repr(plugins) == ( 34 "TypedCallableRegistry(active='', " "registered=['new_plugin'])" 35 ) 36 37 plugins.enable("new_plugin") 38 assert plugins.names() == ["new_plugin"] 39 assert plugins.active == "new_plugin" 40 assert plugins.get()(3) == 9 41 assert repr(plugins) == ( 42 "TypedCallableRegistry(active='new_plugin', " "registered=['new_plugin'])" 43 ) 44 45 46def test_plugin_registry_extra_options(): 47 plugins = GeneralCallableRegistry() 48 49 plugins.register("metadata_plugin", lambda x, p=2: x ** p) 50 plugins.enable("metadata_plugin") 51 assert plugins.get()(3) == 9 52 53 plugins.enable("metadata_plugin", p=3) 54 assert plugins.active == "metadata_plugin" 55 assert plugins.get()(3) == 27 56 57 # enabling without changing name 58 plugins.enable(p=2) 59 assert plugins.active == "metadata_plugin" 60 assert plugins.get()(3) == 9 61 62 63def test_plugin_registry_global_settings(): 64 plugins = GeneralCallableRegistry() 65 66 # we need some default plugin, but we won't do anything with it 67 plugins.register("default", lambda x: x) 68 plugins.enable("default") 69 70 # default value of the global flag 71 assert plugins.global_setting is None 72 73 # enabling changes the global state, not the options 74 plugins.enable(global_setting=True) 75 assert plugins.global_setting is True 76 assert plugins._options == {} 77 78 # context manager changes global state temporarily 79 with plugins.enable(global_setting="temp"): 80 assert plugins.global_setting == "temp" 81 assert plugins._options == {} 82 assert plugins.global_setting is True 83 assert plugins._options == {} 84 85 86def test_plugin_registry_context(): 87 plugins = GeneralCallableRegistry() 88 89 plugins.register("default", lambda x, p=2: x ** p) 90 91 # At first there is no plugin enabled 92 assert plugins.active == "" 93 assert plugins.options == {} 94 95 # Make sure the context is set and reset correctly 96 with plugins.enable("default", p=6): 97 assert plugins.active == "default" 98 assert plugins.options == {"p": 6} 99 100 assert plugins.active == "" 101 assert plugins.options == {} 102 103 # Make sure the context is reset even if there is an error 104 try: 105 with plugins.enable("default", p=6): 106 assert plugins.active == "default" 107 assert plugins.options == {"p": 6} 108 raise ValueError() 109 except ValueError: 110 pass 111 112 assert plugins.active == "" 113 assert plugins.options == {} 114 115 # Enabling without specifying name uses current name 116 plugins.enable("default", p=2) 117 118 with plugins.enable(p=6): 119 assert plugins.active == "default" 120 assert plugins.options == {"p": 6} 121 122 assert plugins.active == "default" 123 assert plugins.options == {"p": 2} 124