pluginify 1.0.0.post11.dev0__py3-none-any.whl → 1.0.0.post41.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,7 @@ import logging
23
23
  import os
24
24
  from pathlib import Path
25
25
  from types import SimpleNamespace
26
+ from typing import Any, cast
26
27
 
27
28
  from lexeme_type.lexeme import Lexeme
28
29
  from pydantic import BaseModel
@@ -74,11 +75,26 @@ class PluginRegistry:
74
75
  pluginify is instantiated.
75
76
  """
76
77
 
77
- def __init__(self, namespace, _test_registry_files=[]):
78
+ def __init__(
79
+ self,
80
+ namespace: str,
81
+ _test_registry_files: list[str] | None = None,
82
+ ) -> None:
78
83
  """Initialize the plugin registry for the namespace provided.
79
84
 
80
85
  Where namespace is the group of plugin packages used to create the plugin
81
86
  registry.
87
+
88
+ Parameters
89
+ ----------
90
+ namespace : str
91
+ The namespace in which plugin packages are registered to. Usually, this
92
+ will be the 'pluginify.plugin_package' namespace, however this can be
93
+ changed by providing a different top-level namespace to the PluginRegistry
94
+ class.
95
+ _test_registry_files : list[str], optional
96
+ Use this for unit testing. If provided, registry files are set
97
+ from this list rather than discovered from entry points.
82
98
  """
83
99
  self.namespace = namespace
84
100
  # Use this for unit testing
@@ -102,7 +118,7 @@ class PluginRegistry:
102
118
  return self._registered_plugins
103
119
 
104
120
  @registered_plugins.setter
105
- def registered_plugins(self, new_value):
121
+ def registered_plugins(self, new_value: dict) -> None:
106
122
  """Set the registered_plugins class attribute.
107
123
 
108
124
  See the registered_plugins property for more information.
@@ -123,7 +139,7 @@ class PluginRegistry:
123
139
  return self._interface_mapping
124
140
 
125
141
  @interface_mapping.setter
126
- def interface_mapping(self, new_value):
142
+ def interface_mapping(self, new_value: dict) -> None:
127
143
  """Set the interface_mapping class attribute.
128
144
 
129
145
  See the interface_mapping property for more information.
@@ -146,9 +162,9 @@ class PluginRegistry:
146
162
 
147
163
  def _set_class_properties(
148
164
  self,
149
- force_reset=False,
150
- rebuild_registries_override=None,
151
- ):
165
+ force_reset: bool = False,
166
+ rebuild_registries_override: bool | None = None,
167
+ ) -> None:
152
168
  """Find all plugins in registered plugin packages.
153
169
 
154
170
  Traverse the ``registered_plugins.json`` of each registered plugin package under
@@ -157,16 +173,16 @@ class PluginRegistry:
157
173
 
158
174
  Parameters
159
175
  ----------
160
- force_reset: bool, default=False
161
- - Whether or not we want to force the plugin registry to recreate its
162
- 'registered_plugins' attribute. This essentially forces a re-read of all
163
- of the registered_plugins.json files and recomputes the master dictionary.
164
- - Useful when we have rebuilt the registry files during runtime.
165
- rebuild_registries_override: bool, default=None
166
- - Whether or not we want to override the value of REBUILD_REGISTIRES set in
167
- the config file for this package to a different boolean value. If None,
168
- use the default value set in the config file.
169
- - Used for unit tests.
176
+ force_reset : bool, optional
177
+ Whether or not we want to force the plugin registry to recreate its
178
+ 'registered_plugins' attribute. This essentially forces a re-read of all
179
+ of the registered_plugins.json files and recomputes the master dictionary.
180
+ Useful when we have rebuilt the registry files during runtime.
181
+ rebuild_registries_override : bool, optional
182
+ Whether or not we want to override the value of REBUILD_REGISTIRES set in
183
+ the config file for this package to a different boolean value. If None,
184
+ use the default value set in the config file.
185
+ Used for unit tests.
170
186
  """
171
187
  # Load the registries here and return them as a dictionary
172
188
  if not hasattr(self, "_registered_plugins") or force_reset:
@@ -212,38 +228,29 @@ class PluginRegistry:
212
228
  )
213
229
  self.interface_mapping = return_tuple.interface_mapping
214
230
  self.registered_plugins = return_tuple.registered_plugins
215
- # Let's test this separately, not at runtime (see validate_all_registries).
216
- # Assume it was tested up front, and no longer needs testing at
217
- # runtime, so we don't fail catastrophically for a single bad
218
- # plugin that may not even be used.
219
- # if not self._is_test:
220
- # self.validate_registry(
221
- # self._registered_plugins,
222
- # "all_registered_plugins",
223
- # )
224
231
 
225
232
  @staticmethod
226
- def _find_registry_files(namespace):
233
+ def _find_registry_files(namespace: str) -> list[str]:
227
234
  """Locate all plugin registry files found under 'namespace'.
228
235
 
229
236
  Parameters
230
237
  ----------
231
- namespace: str
232
- - The namespace in which plugin packages are registered to. Usually, this
233
- will be the 'pluginify.plugin_package' namespace, however this can be
234
- changed by providing a different top-level namespace to the PluginRegistry
235
- class.
238
+ namespace : str
239
+ The namespace in which plugin packages are registered to. Usually, this
240
+ will be the 'pluginify.plugin_package' namespace, however this can be
241
+ changed by providing a different top-level namespace to the PluginRegistry
242
+ class.
236
243
 
237
244
  Returns
238
245
  -------
239
- registry_files: list[str]
240
- - A list of filepaths corresponding to expected registered_plugins.json
241
- files for all plugin packages found under namespace.
246
+ registry_files : list[str]
247
+ A list of filepaths corresponding to expected registered_plugins.json
248
+ files for all plugin packages found under namespace.
242
249
 
243
250
  Raises
244
251
  ------
245
- PluginRegistryError:
246
- - Occurs if a package is potentially missing an __init__.py file.
252
+ PluginRegistryError
253
+ Occurs if a package is potentially missing an __init__.py file.
247
254
  """
248
255
  registry_files = [] # Collect the paths to the registry files here
249
256
  for pkg in metadata.entry_points(group=namespace):
@@ -263,7 +270,7 @@ class PluginRegistry:
263
270
  return registry_files
264
271
 
265
272
  @staticmethod
266
- def _load_registry(reg_path):
273
+ def _load_registry(reg_path: str) -> dict:
267
274
  """Load the plugin registry found at 'reg_path'.
268
275
 
269
276
  All files provided to this function share the same namespace. Usually, this
@@ -272,23 +279,23 @@ class PluginRegistry:
272
279
 
273
280
  Parameters
274
281
  ----------
275
- reg_path: str
276
- - The absolute path to the plugin registry file for a certain plugin
277
- package.
282
+ reg_path : str
283
+ The absolute path to the plugin registry file for a certain plugin
284
+ package.
278
285
 
279
286
  Returns
280
287
  -------
281
- registry: dict
282
- - A dictionary representing the contents of a plugin registry file. Can
283
- include top-level keys such as 'yaml_based' or 'module_based' each of
284
- which is another dictionary containing interfaces of that type, which
285
- are also dictionaries containing plugins that correspond to that
286
- interface.
288
+ registry : dict
289
+ A dictionary representing the contents of a plugin registry file. Can
290
+ include top-level keys such as 'yaml_based' or 'module_based' each of
291
+ which is another dictionary containing interfaces of that type, which
292
+ are also dictionaries containing plugins that correspond to that
293
+ interface.
287
294
 
288
295
  Raises
289
296
  ------
290
- FileNotFoundError:
291
- - Raised if 'reg_path' doesn't exist.
297
+ FileNotFoundError
298
+ Raised if 'reg_path' doesn't exist.
292
299
  """
293
300
  # if this is a yaml file, this is used for testing
294
301
  if Path(reg_path).suffix == ".yaml":
@@ -298,36 +305,40 @@ class PluginRegistry:
298
305
  with open(reg_path, "r") as fo:
299
306
  registry = json.load(fo)
300
307
 
301
- return registry
308
+ return cast(dict, registry)
302
309
 
303
310
  @staticmethod
304
- def _parse_registry(interface_mapping, registered_plugins, registry):
311
+ def _parse_registry(
312
+ interface_mapping: dict,
313
+ registered_plugins: dict,
314
+ registry: dict,
315
+ ) -> SimpleNamespace:
305
316
  """Parse all plugins found under a package's plugin registry.
306
317
 
307
318
  Parameters
308
319
  ----------
309
- interface_mapping: dict
310
- - Dictionary of interface types and interfaces of that type.
311
- pluginify has three types of interfaces, though only two are commonly used
312
- (yaml_based, class_based). This dictionary has top level keys of all
313
- interface types, with their values being the list of unique interfaces
314
- that inherit that type.
315
- registered_plugins: dict
316
- - A dictionary of every plugin's metadata found within the plugin_registry's
317
- namespace.
318
- registry: dict
319
- - A dictionary representing the contents of a plugin registry file. Can
320
- include top-level keys such as 'yaml_based' or 'class_based' each of
321
- which is another dictionary containing interfaces of that type, which
322
- are also dictionaries containing plugins that correspond to that
323
- interface.
320
+ interface_mapping : dict
321
+ Dictionary of interface types and interfaces of that type.
322
+ pluginify has three types of interfaces, though only two are commonly used
323
+ (yaml_based, class_based). This dictionary has top level keys of all
324
+ interface types, with their values being the list of unique interfaces
325
+ that inherit that type.
326
+ registered_plugins : dict
327
+ A dictionary of every plugin's metadata found within the plugin_registry's
328
+ namespace.
329
+ registry : dict
330
+ A dictionary representing the contents of a plugin registry file. Can
331
+ include top-level keys such as 'yaml_based' or 'class_based' each of
332
+ which is another dictionary containing interfaces of that type, which
333
+ are also dictionaries containing plugins that correspond to that
334
+ interface.
324
335
 
325
336
  Returns
326
337
  -------
327
- return_tuple: SimpleNamespace
328
- - A SimpleNamespace object containing updated values of the variables
329
- ['interface_mapping', 'registered_plugins'] which are dictionaries. See
330
- comments about those two variables in the parameters section above.
338
+ return_tuple : SimpleNamespace
339
+ A SimpleNamespace object containing updated values of the variables
340
+ ['interface_mapping', 'registered_plugins'] which are dictionaries. See
341
+ comments about those two variables in the parameters section above.
331
342
  """
332
343
  for plugin_type in registry:
333
344
  if plugin_type not in registered_plugins:
@@ -351,7 +362,11 @@ class PluginRegistry:
351
362
  )
352
363
  return return_tuple
353
364
 
354
- def get_plugin_metadata(self, interface_obj, plugin_name):
365
+ def get_plugin_metadata(
366
+ self,
367
+ interface_obj: Any,
368
+ plugin_name: str | tuple[str, str],
369
+ ) -> dict:
355
370
  """Retrieve a plugin's metadata.
356
371
 
357
372
  Where the metadata of the plugin matches the plugin's corresponding entry in the
@@ -359,15 +374,15 @@ class PluginRegistry:
359
374
 
360
375
  Parameters
361
376
  ----------
362
- interface_obj: Interface Object
363
- - The object representing the interface class requesting plugin metadata.
364
- plugin_name: str or tuple(str)
365
- - The name of the plugin whose metadata we want.
377
+ interface_obj : Interface Object
378
+ The object representing the interface class requesting plugin metadata.
379
+ plugin_name : str or tuple[str]
380
+ The name of the plugin whose metadata we want.
366
381
 
367
382
  Returns
368
383
  -------
369
- metadata: dict
370
- - A dictionary of metadata for the requested plugin.
384
+ metadata : dict
385
+ A dictionary of metadata for the requested plugin.
371
386
  """
372
387
  interface_registry = self.registered_plugins.get(
373
388
  interface_obj.interface_type, {}
@@ -397,7 +412,7 @@ class PluginRegistry:
397
412
  "plugin exists, please run 'pluginify create'."
398
413
  )
399
414
 
400
- return metadata
415
+ return cast(dict, metadata)
401
416
 
402
417
  def load_plugin(self, data: dict, _expand: bool = False) -> BaseModel:
403
418
  """
@@ -482,28 +497,32 @@ class PluginRegistry:
482
497
  return model_class(**data) # type: ignore[no-any-return]
483
498
 
484
499
  def get_yaml_plugin(
485
- self, interface_obj, name, rebuild_registries=None, _expand=False
486
- ):
500
+ self,
501
+ interface_obj: Any,
502
+ name: str | tuple[str, str],
503
+ rebuild_registries: bool | None = None,
504
+ _expand: bool = False,
505
+ ) -> Any:
487
506
  """Get a YAML plugin by its name.
488
507
 
489
508
  Parameters
490
509
  ----------
491
- interface_obj: Interface Object
492
- - The object representing the interface class requesting this yaml plugin.
493
- name: str or tuple(str)
494
- - The name of the yaml-based plugin. Either a single string or a tuple of
495
- strings for product plugins.
496
- rebuild_registries: bool (default=None)
497
- - Whether or not to rebuild the registries if get_plugin fails. If set to
498
- None, default to True. If specified, use the input value of
499
- rebuild_registries, which should be a boolean value. If rebuild registries
500
- is true and get_plugin fails, rebuild the plugin registry, call then call
501
- get_plugin once more with rebuild_registries toggled off, so it only gets
502
- rebuilt once.
503
- _expand: private bool (default=False)
504
- - If true, fully expand the workflow plugin in place. Otherwise, load as is
505
- done usually. This should only be used for the
506
- 'geoips expand <workflow>' command.
510
+ interface_obj : Interface Object
511
+ The object representing the interface class requesting this yaml plugin.
512
+ name : str or tuple[str]
513
+ The name of the yaml-based plugin. Either a single string or a tuple of
514
+ strings for product plugins.
515
+ rebuild_registries : bool, optional
516
+ Whether or not to rebuild the registries if get_plugin fails. If set to
517
+ None, default to True. If specified, use the input value of
518
+ rebuild_registries, which should be a boolean value. If rebuild registries
519
+ is true and get_plugin fails, rebuild the plugin registry, call then call
520
+ get_plugin once more with rebuild_registries toggled off, so it only gets
521
+ rebuilt once.
522
+ _expand : bool, default False
523
+ If true, fully expand the workflow plugin in place. Otherwise, load as is
524
+ done usually. This should only be used for the
525
+ 'geoips expand <workflow>' command.
507
526
  """
508
527
  if _expand and interface_obj.name != "workflows":
509
528
  raise AssertionError(
@@ -634,15 +653,15 @@ class PluginRegistry:
634
653
  validated = interface_obj.validator.validate(plugin)
635
654
  return interface_obj._plugin_yaml_to_obj(name, validated)
636
655
 
637
- def get_yaml_plugins(self, interface_obj):
656
+ def get_yaml_plugins(self, interface_obj: Any) -> list:
638
657
  """Retrieve all yaml plugin objects for this interface.
639
658
 
640
659
  Parameters
641
660
  ----------
642
- interface_obj: Interface Object
643
- - The object representing the interface class requesting all plugins.
661
+ interface_obj : Interface Object
662
+ The object representing the interface class requesting all plugins.
644
663
  """
645
- plugins = []
664
+ plugins: list = []
646
665
  registered_yaml_plugins = self.registered_yaml_based_plugins
647
666
  if interface_obj.name not in registered_yaml_plugins:
648
667
  LOG.debug("No plugins found for '%s' interface.", interface_obj.name)
@@ -651,7 +670,12 @@ class PluginRegistry:
651
670
  plugins.append(self.get_yaml_plugin(interface_obj, name))
652
671
  return plugins
653
672
 
654
- def get_class_plugin(self, interface_obj, name, rebuild_registries=None):
673
+ def get_class_plugin(
674
+ self,
675
+ interface_obj: Any,
676
+ name: str,
677
+ rebuild_registries: bool | None = None,
678
+ ) -> Any:
655
679
  """Retrieve a class plugin from this interface by name.
656
680
 
657
681
  In pluginify's current state, a class plugin can be a derived plugin object
@@ -660,27 +684,27 @@ class PluginRegistry:
660
684
 
661
685
  Parameters
662
686
  ----------
663
- interface_obj: Interface Object
664
- - The object representing the interface class requesting this class plugin.
665
- name: str
666
- - The name the desired plugin.
667
- rebuild_registries: bool (default=None)
668
- - Whether or not to rebuild the registries if get_plugin fails. If set to
669
- None, default to True. If specified, use the input value of
670
- rebuild_registries, which should be a boolean value. If rebuild registries
671
- is true and get_plugin fails, rebuild the plugin registry, call then call
672
- get_plugin once more with rebuild_registries toggled off, so it only gets
673
- rebuilt once.
687
+ interface_obj : Interface Object
688
+ The object representing the interface class requesting this class plugin.
689
+ name : str
690
+ The name the desired plugin.
691
+ rebuild_registries : bool, optional
692
+ Whether or not to rebuild the registries if get_plugin fails. If set to
693
+ None, default to True. If specified, use the input value of
694
+ rebuild_registries, which should be a boolean value. If rebuild registries
695
+ is true and get_plugin fails, rebuild the plugin registry, call then call
696
+ get_plugin once more with rebuild_registries toggled off, so it only gets
697
+ rebuilt once.
674
698
 
675
699
  Returns
676
700
  -------
677
- An object of type ``<interface>Plugin`` where ``<interface>`` is the name of
678
- this interface.
701
+ An object of type ``<interface>Plugin`` where ``<interface>`` is the name of
702
+ this interface.
679
703
 
680
704
  Raises
681
705
  ------
682
706
  PluginError
683
- If the specified plugin isn't found within the interface.
707
+ If the specified plugin isn't found within the interface.
684
708
  """
685
709
  try:
686
710
  registered_class_plugins = self.registered_plugins["class_based"]
@@ -731,6 +755,11 @@ class PluginRegistry:
731
755
  interface_obj, name, rebuild_registries, err_str, PluginRegistryError
732
756
  )
733
757
  spec = util.spec_from_file_location(module_path, abspath)
758
+ if spec is None or spec.loader is None:
759
+ raise PluginError(
760
+ f"Error: could not create a module spec for '{module_path}' at "
761
+ f"'{abspath}'. Reinstall your package and try again."
762
+ )
734
763
  module = util.module_from_spec(spec)
735
764
  spec.loader.exec_module(module)
736
765
 
@@ -750,7 +779,7 @@ class PluginRegistry:
750
779
  interface_obj.plugin_is_valid(plugin)
751
780
  return plugin
752
781
 
753
- def get_class_plugins(self, interface_obj):
782
+ def get_class_plugins(self, interface_obj: Any) -> list:
754
783
  """Retrieve all class plugins for this interface.
755
784
 
756
785
  In pluginify's current state, this will grab all true class-based plugins and
@@ -759,10 +788,10 @@ class PluginRegistry:
759
788
 
760
789
  Parameters
761
790
  ----------
762
- interface_obj: Interface Object
763
- - The object representing the interface class requesting all plugins.
791
+ interface_obj : Interface Object
792
+ The object representing the interface class requesting all plugins.
764
793
  """
765
- plugins = []
794
+ plugins: list = []
766
795
  # All plugin interfaces are explicitly imported in
767
796
  # pluginify/interfaces/__init__.py
768
797
  # self.name comes explicitly from one of the interfaces that are
@@ -794,8 +823,13 @@ class PluginRegistry:
794
823
  return plugins
795
824
 
796
825
  def retry_get_plugin(
797
- self, interface_obj, name, rebuild_registries, err_str, err_type=PluginError
798
- ):
826
+ self,
827
+ interface_obj: Any,
828
+ name: str | tuple[str, str],
829
+ rebuild_registries: bool | None,
830
+ err_str: str,
831
+ err_type: type[Exception] = PluginError,
832
+ ) -> Any:
799
833
  """Rerun self.get_plugin, but call 'pluginify create' beforehand.
800
834
 
801
835
  By running 'pluginify create', we automate the registration of plugins under a
@@ -805,20 +839,20 @@ class PluginRegistry:
805
839
 
806
840
  Parameters
807
841
  ----------
808
- interface_obj: Interface Object
809
- - The object representing the interface class requesting this plugin.
810
- name: str or tuple(str)
811
- - The name of the yaml plugin. Either a single string or a tuple of strings
812
- for product plugins.
813
- rebuild_registries: bool
814
- - Whether or not to rebuild the registries if get_plugin fails. If set to
815
- true and get_plugin fails, rebuild the plugin registry, call then call
816
- get_plugin once more with rebuild_registries toggled off, so it only gets
817
- rebuilt once.
818
- err_str: string
819
- - The error to be reported.
820
- err_type: Exception-based Class
821
- - The class of exception to be raised.
842
+ interface_obj : Interface Object
843
+ The object representing the interface class requesting this plugin.
844
+ name : str or tuple[str]
845
+ The name of the yaml plugin. Either a single string or a tuple of strings
846
+ for product plugins.
847
+ rebuild_registries : bool
848
+ Whether or not to rebuild the registries if get_plugin fails. If set to
849
+ true and get_plugin fails, rebuild the plugin registry, call then call
850
+ get_plugin once more with rebuild_registries toggled off, so it only gets
851
+ rebuilt once.
852
+ err_str : str
853
+ The error to be reported.
854
+ err_type : Exception-based Class
855
+ The class of exception to be raised.
822
856
  """
823
857
  if rebuild_registries:
824
858
  LOG.info(
@@ -840,7 +874,11 @@ class PluginRegistry:
840
874
  else:
841
875
  raise err_type(err_str)
842
876
 
843
- def create_registries(self, packages=None, save_type="json") -> None:
877
+ def create_registries(
878
+ self,
879
+ packages: list[str] | None = None,
880
+ save_type: str = "json",
881
+ ) -> None:
844
882
  """Create one or more plugin registry files.
845
883
 
846
884
  By default, this command will create all plugin registry files for all
@@ -850,23 +888,23 @@ class PluginRegistry:
850
888
 
851
889
  Parameters
852
890
  ----------
853
- packages: list[str], default=None
854
- - A list of plugin package names corresponding to a namespace whose
855
- registries we want to create.
856
- save_type: str, default="json"
857
- - Format to write registries to. This will also be the file extension. Valid
858
- options are either 'json' or 'yaml'.
891
+ packages : list[str], optional
892
+ A list of plugin package names corresponding to a namespace whose
893
+ registries we want to create.
894
+ save_type : str, optional
895
+ Format to write registries to. This will also be the file extension. Valid
896
+ options are either 'json' or 'yaml'.
859
897
 
860
898
  Raises
861
899
  ------
862
- ValueError:
863
- - Raised if 'save_type' is provided but is not one of ['json', 'yaml']
864
- TypeError:
865
- - Raised if packages is provided and is not a list of strings.
866
- PluginRegistryError:
867
- - Raised if one or more of the packages provided is not a valid
868
- plugin package under the provided namespace, or if the associated
869
- namespace provided is not a valid namespace.
900
+ ValueError
901
+ Raised if 'save_type' is provided but is not one of ['json', 'yaml']
902
+ TypeError
903
+ Raised if packages is provided and is not a list of strings.
904
+ PluginRegistryError
905
+ Raised if one or more of the packages provided is not a valid
906
+ plugin package under the provided namespace, or if the associated
907
+ namespace provided is not a valid namespace.
870
908
  """
871
909
  if save_type not in ["json", "yaml"]:
872
910
  raise ValueError(
@@ -890,7 +928,10 @@ class PluginRegistry:
890
928
  LOG.debug(plugin_packages)
891
929
  create_plugin_registries(plugin_packages, save_type, self.namespace)
892
930
 
893
- def delete_registries(self, packages=None) -> None:
931
+ def delete_registries(
932
+ self,
933
+ packages: list[str] | None = None,
934
+ ) -> None:
894
935
  """Delete one or more plugin registry files.
895
936
 
896
937
  By default, this command will delete all plugin registry files found in all
@@ -900,21 +941,21 @@ class PluginRegistry:
900
941
 
901
942
  Parameters
902
943
  ----------
903
- packages: list[str], default=None
904
- - A list of plugin package names corresponding to a namespace whose
905
- registries we want to delete.
944
+ packages : list[str], optional
945
+ A list of plugin package names corresponding to a namespace whose
946
+ registries we want to delete.
906
947
 
907
948
  Raises
908
949
  ------
909
- TypeError:
910
- - Raised if packages is provided and is not a list of strings.
911
- FileNotFoundError:
912
- - Raised if a registry file could not be found in one or more plugin
913
- packages under self.namespace.
914
- PluginRegistryError:
915
- - Raised if one or more of the packages provided is not a valid
916
- plugin package under the provided namespace, or if the associated
917
- namespace provided is not a valid namespace.
950
+ TypeError
951
+ Raised if packages is provided and is not a list of strings.
952
+ FileNotFoundError
953
+ Raised if a registry file could not be found in one or more plugin
954
+ packages under self.namespace.
955
+ PluginRegistryError
956
+ Raised if one or more of the packages provided is not a valid
957
+ plugin package under the provided namespace, or if the associated
958
+ namespace provided is not a valid namespace.
918
959
  """
919
960
  if packages:
920
961
  self._validate_packages_input(packages)
@@ -947,25 +988,25 @@ class PluginRegistry:
947
988
  )
948
989
  continue
949
990
 
950
- def _validate_packages_input(self, packages):
991
+ def _validate_packages_input(self, packages: list[str]) -> None:
951
992
  """Validate that packages is a list of strings.
952
993
 
953
994
  If not, then raise a TypeError indicating what was formatted incorrectly.
954
995
 
955
996
  Parameters
956
997
  ----------
957
- packages: list[str], default=None
958
- - A list of plugin package names corresponding to a namespace whose
959
- registries we want to delete.
998
+ packages : list[str]
999
+ A list of plugin package names corresponding to a namespace whose
1000
+ registries we want to delete.
960
1001
 
961
1002
  Raises
962
1003
  ------
963
- TypeError:
964
- - Raised if packages is provided and is not a list of strings.
965
- PluginRegistryError:
966
- - Raised if one or more of the packages provided is not a valid
967
- plugin package under the provided namespace, or if the associated
968
- namespace provided is not a valid namespace.
1004
+ TypeError
1005
+ Raised if packages is provided and is not a list of strings.
1006
+ PluginRegistryError
1007
+ Raised if one or more of the packages provided is not a valid
1008
+ plugin package under the provided namespace, or if the associated
1009
+ namespace provided is not a valid namespace.
969
1010
  """
970
1011
  if not isinstance(packages, list):
971
1012
  raise TypeError(