22import logging
33from pathlib import Path
44from types import ModuleType
5- from typing import Optional
5+ from typing import List , Optional
66
77logger = logging .getLogger (__name__ )
88
9- PLUGIN_TYPE_DIST_INSPECTOR = "dist-inspector"
10- SUPPORTED_PLUGIN_TYPES = [PLUGIN_TYPE_DIST_INSPECTOR ]
9+ PLUGIN_HOOK_PRE_DOWNLOAD = "pre_download"
10+ PLUGIN_HOOK_PRE_EXTRACT = "pre_extract"
11+ SUPPORTED_PLUGIN_HOOKS = [PLUGIN_HOOK_PRE_DOWNLOAD , PLUGIN_HOOK_PRE_EXTRACT ]
1112
1213
1314class Plugin (metaclass = abc .ABCMeta ):
1415 @abc .abstractmethod
15- def plugin_type (self ) -> str :
16+ def provided_hooks (self ) -> List [ str ] :
1617 raise NotImplementedError
1718
1819 @property
@@ -21,22 +22,40 @@ def name(self) -> str:
2122 raise NotImplementedError
2223
2324
24- class DistInspectorPlugin (Plugin ):
25+ class LoadedPlugin (Plugin ):
2526 def __init__ (self , name : str , loaded_module : ModuleType ):
26- assert loaded_module .plugin_type () == PLUGIN_TYPE_DIST_INSPECTOR
27- if not hasattr (loaded_module , "pre_download" ) or not hasattr (
28- loaded_module , "pre_extract"
29- ):
27+ self ._pre_download = None
28+ self ._pre_extract = None
29+ if not hasattr (loaded_module , "provided_hooks" ):
3030 raise ValueError (
31- f'Plugin "{ name } " of type { PLUGIN_TYPE_DIST_INSPECTOR } is'
32- "missing pre_download and/or pre_extract definitions"
31+ f"Ignoring plugin { name } due to missing provided_hooks definition"
3332 )
33+ for hook in loaded_module .provided_hooks ():
34+ if hook == PLUGIN_HOOK_PRE_DOWNLOAD :
35+ if not hasattr (loaded_module , "pre_download" ):
36+ raise ValueError (
37+ f'Plugin "{ name } " wants to register a pre-download hook but '
38+ "does not define a pre_download method"
39+ )
40+ self ._pre_download = loaded_module .pre_download
41+ elif hook == PLUGIN_HOOK_PRE_EXTRACT :
42+ if not hasattr (loaded_module , "pre_extract" ):
43+ raise ValueError (
44+ f'Plugin "{ name } " wants to register a pre-extract hook but '
45+ "does not define a pre_extract method"
46+ )
47+ self ._pre_extract = loaded_module .pre_extract
48+ else :
49+ raise ValueError (
50+ f'Plugin "{ name } " wants to register a hook of unknown type:'
51+ '"{hook}"'
52+ )
3453
3554 self ._name = name
3655 self ._module = loaded_module
3756
38- def plugin_type (self ) -> str :
39- return self ._module .plugin_type ()
57+ def provided_hooks (self ) -> List [ str ] :
58+ return self ._module .provided_hooks ()
4059
4160 @property
4261 def name (self ) -> str :
@@ -46,26 +65,19 @@ def pre_download(self, url: str, filename: str, digest: str) -> None:
4665 # contract: `pre_download` raises `ValueError` to terminate
4766 # the operation that intends to download `filename` from `url`
4867 # with hash `digest`
49- self ._module .pre_download (url = url , filename = filename , digest = digest )
68+ if self ._pre_download is not None :
69+ self ._pre_download (url = url , filename = filename , digest = digest )
5070
5171 def pre_extract (self , dist : Path ) -> None :
5272 # contract: `pre_extract` raises `ValueError` to terminate
5373 # the operation that intends to unarchive `dist`
54- self ._module .pre_extract (dist )
74+ if self ._pre_extract is not None :
75+ self ._module .pre_extract (dist )
5576
5677
57- def plugin_from_module (name : str , loaded_module : ModuleType ) -> Optional [Plugin ]:
58- if not hasattr (loaded_module , "plugin_type" ):
59- logger .warning ("Ignoring plugin %s due to missing plugin_type definition" , name )
60- plugin_type = loaded_module .plugin_type ()
61- if plugin_type not in SUPPORTED_PLUGIN_TYPES :
62- logger .warning (
63- "Ignoring plugin %s due to unknown plugin type: %s" , name , plugin_type
64- )
65-
66- if plugin_type == PLUGIN_TYPE_DIST_INSPECTOR :
67- try :
68- return DistInspectorPlugin (name , loaded_module )
69- except ValueError as e :
70- logger .warning ("Ignoring plugin %s due to error: %s" , name , e )
78+ def plugin_from_module (name : str , loaded_module : ModuleType ) -> Optional [LoadedPlugin ]:
79+ try :
80+ return LoadedPlugin (name , loaded_module )
81+ except ValueError as e :
82+ logger .warning ("Ignoring plugin %s due to error: %s" , name , e )
7183 return None
0 commit comments