Refactor provider verification logic into intake.provider

This commit is contained in:
Tim Van Baak 2022-08-14 00:34:07 -07:00
parent 982c7ad388
commit f6fed08e26
2 changed files with 142 additions and 55 deletions

View File

@ -4,7 +4,17 @@ import os
from signal import signal, SIGPIPE, SIG_DFL from signal import signal, SIGPIPE, SIG_DFL
import sys import sys
from intake.provider import BaseSettings, load_provider from intake.provider import (
AttributeTypeError,
FunctionSignatureError,
load_provider,
RequiredAttributeMissingError,
verify_action,
verify_oncreate,
verify_ondelete,
verify_settings,
verify_update,
)
def command_test(args): def command_test(args):
@ -40,72 +50,60 @@ def command_test(args):
ret = 1 ret = 1
continue continue
# Settings class # Settings class
if not hasattr(provider, "Settings"): try:
verify_settings(provider)
print(" o Settings")
except RequiredAttributeMissingError:
print(" x Missing Settings class") print(" x Missing Settings class")
ret = 1 ret = 1
else: except AttributeTypeError:
settings = getattr(provider, "Settings")
if not issubclass(settings, BaseSettings):
print(" x Settings class does not inherit from intake.BaseSettings") print(" x Settings class does not inherit from intake.BaseSettings")
ret = 1 ret = 1
else:
print(" o Settings")
# update function # update function
if not hasattr(provider, "Settings"): try:
verify_update(provider)
print(" o update")
except RequiredAttributeMissingError:
print(" x Missing update(config, state)") print(" x Missing update(config, state)")
ret = 1 ret = 1
else: except AttributeTypeError:
update = getattr(provider, "update")
if not callable(update):
print(" x update is not callable") print(" x update is not callable")
ret = 1 ret = 1
else: except FunctionSignatureError:
update_sig = inspect.signature(update)
if list(update_sig.parameters) != ["config", "state"]:
print(" x update does not have signature (config, state)") print(" x update does not have signature (config, state)")
ret = 1 ret = 1
else:
print(" o update")
# on-create hook # on-create hook
if hasattr(provider, "on_create"): try:
on_create = getattr(provider, "on_create") if verify_oncreate(provider):
if not callable(on_create): print(" o on_create")
except AttributeTypeError:
print(" x on_create is not callable") print(" x on_create is not callable")
ret = 1 ret = 1
else: except FunctionSignatureError:
create_sig = inspect.signature(on_create)
if list(create_sig.parameters) != ["config", "state", "item"]:
print(" x on_create does not have signature (config, state, item)") print(" x on_create does not have signature (config, state, item)")
ret = 1 ret = 1
else:
print(" o on_create")
# on-delete hook # on-delete hook
if hasattr(provider, "on_delete"): try:
on_delete = getattr(provider, "on_delete") if verify_ondelete(provider):
if not callable(on_delete): print(" o on_delete")
except AttributeTypeError:
print(" x on_delete is not callable") print(" x on_delete is not callable")
ret = 1 ret = 1
else: except FunctionSignatureError:
delete_sig = inspect.signature(on_delete)
if list(delete_sig.parameters) != ["config", "state", "item"]:
print(" x on_delete does not have signature (config, state, item)") print(" x on_delete does not have signature (config, state, item)")
ret = 1 ret = 1
else:
print(" o on_delete")
# actions # actions
actions = [name for name in vars(provider) if name.startswith("action_")] actions = [name for name in vars(provider) if name.startswith("action_")]
for action_name in actions: for action_name in actions:
action = getattr(provider, action_name) try:
if not callable(action): if verify_action(provider, action_name):
print(f" o {action_name}")
except AttributeTypeError:
print(f" x {action_name} is not callable") print(f" x {action_name} is not callable")
ret = 1 ret = 1
else: except FunctionSignatureError:
action_sig = inspect.signature(action)
if list(action_sig.parameters) != ["config", "state", "item"]:
print(f" x {action_name} does not have signature (config, state, item)") print(f" x {action_name} does not have signature (config, state, item)")
ret = 1 ret = 1
else:
print(f" o {action_name}")
print("Done") print("Done")
return ret return ret

View File

@ -1,4 +1,5 @@
import importlib.util import importlib.util
import inspect
import os import os
import sys import sys
@ -98,3 +99,91 @@ def load_provider(search_paths, provider_name):
return provider return provider
return None return None
class ProviderError(Exception):
"""A provider's attributes are incorrect."""
class RequiredAttributeMissingError(ProviderError):
"""A provider is missing a required attribute."""
class AttributeTypeError(ProviderError):
"""A provider has an attribute with a wrong type."""
class FunctionSignatureError(ProviderError):
"""A provider has a function attribute with the wrong signature."""
def verify_settings(provider):
"""
Verify that a provider's Settings is valid.
"""
if not hasattr(provider, "Settings"):
raise RequiredAttributeMissingError()
settings = getattr(provider, "Settings")
if not issubclass(settings, BaseSettings):
raise AttributeTypeError()
return True
def verify_update(provider):
"""
Verify that a provider's update() is valid.
"""
if not hasattr(provider, "update"):
raise RequiredAttributeMissingError()
update = getattr(provider, "update")
if not callable(update):
raise AttributeTypeError()
update_sig = inspect.signature(update)
if list(update_sig.parameters) != ["config", "state"]:
raise FunctionSignatureError()
return True
def verify_oncreate(provider):
"""
Verify that a provider's on_create() is valid.
"""
if not hasattr(provider, "on_create"):
return False
on_create = getattr(provider, "on_create")
if not callable(on_create):
raise AttributeTypeError()
create_sig = inspect.signature(on_create)
if list(create_sig.parameters) != ["config", "state", "item"]:
raise FunctionSignatureError()
return True
def verify_ondelete(provider):
"""
Verify that a provider's on_delete() is valid.
"""
if not hasattr(provider, "on_delete"):
return False
on_delete = getattr(provider, "on_delete")
if not callable(on_delete):
raise AttributeTypeError()
delete_sig = inspect.signature(on_delete)
if list(delete_sig.parameters) != ["config", "state", "item"]:
raise FunctionSignatureError()
return True
def verify_action(provider, name):
"""
Verify that a provider's action_*() is valid.
"""
action_name = name if name.startswith("action_") else f"action_{name}"
if not hasattr(provider, "action_name"):
return False
action = getattr(provider, action_name)
if not callable(action):
raise AttributeTypeError()
action_sig = inspect.signature(action)
if list(action_sig.parameters) != ["config", "state", "item"]:
raise FunctionSignatureError()
return True