55
66"""Handles registering field attributes for spock classes -- deals with the recursive nature of dependencies"""
77
8+ import importlib
9+ import sys
810from abc import ABC , abstractmethod
911from enum import EnumMeta
1012from typing import List , Type
1113
1214from attr import NOTHING , Attribute
1315
14- from spock .args import SpockArguments
1516from spock .backend .spaces import AttributeSpace , BuilderSpace , ConfigSpace
16- from spock .exceptions import _SpockInstantiationError , _SpockNotOptionalError
17- from spock .utils import _check_iterable , _is_spock_instance , _is_spock_tune_instance
17+ from spock .exceptions import (
18+ _SpockInstantiationError ,
19+ _SpockNotOptionalError ,
20+ _SpockValueError ,
21+ )
22+ from spock .utils import (
23+ _check_iterable ,
24+ _is_spock_instance ,
25+ _is_spock_tune_instance ,
26+ _SpockVariadicGenericAlias ,
27+ )
1828
1929
2030class RegisterFieldTemplate (ABC ):
@@ -318,6 +328,69 @@ def _handle_and_register_enum(
318328 builder_space .spock_space [enum_cls .__name__ ] = attr_space .field
319329
320330
331+ class RegisterCallableField (RegisterFieldTemplate ):
332+ """Class that registers callable types
333+
334+ Attributes:
335+ special_keys: dictionary to check special keys
336+
337+ """
338+
339+ def __init__ (self ):
340+ """Init call to RegisterSimpleField
341+
342+ Args:
343+ """
344+ super (RegisterCallableField , self ).__init__ ()
345+
346+ def handle_attribute_from_config (
347+ self , attr_space : AttributeSpace , builder_space : BuilderSpace
348+ ):
349+ """Handles setting a simple attribute when it is a spock class type
350+
351+ Args:
352+ attr_space: holds information about a single attribute that is mapped to a ConfigSpace
353+ builder_space: named_tuple containing the arguments and spock_space
354+
355+ Returns:
356+ """
357+ # These are always going to be strings... cast just in case
358+ str_field = str (
359+ builder_space .arguments [attr_space .config_space .name ][
360+ attr_space .attribute .name
361+ ]
362+ )
363+ module , fn = str_field .rsplit ("." , 1 )
364+ try :
365+ call_ref = getattr (importlib .import_module (module ), fn )
366+ attr_space .field = call_ref
367+ except Exception as e :
368+ raise _SpockValueError (
369+ f"Attempted to import module { module } and callable { fn } however it could not be found on the current "
370+ f"python path: { e } "
371+ )
372+
373+ def handle_optional_attribute_type (
374+ self , attr_space : AttributeSpace , builder_space : BuilderSpace
375+ ):
376+ """Not implemented for this type
377+
378+ Args:
379+ attr_space: holds information about a single attribute that is mapped to a ConfigSpace
380+ builder_space: named_tuple containing the arguments and spock_space
381+
382+ Raises:
383+ _SpockNotOptionalError
384+
385+ """
386+ print ("hi" )
387+ raise _SpockNotOptionalError (
388+ f"Parameter `{ attr_space .attribute .name } ` within `{ attr_space .config_space .name } ` is of "
389+ f"type `{ type (attr_space .attribute .type )} ` which seems to be unsupported -- "
390+ f"are you missing an @spock decorator on a base python class?"
391+ )
392+
393+
321394class RegisterSimpleField (RegisterFieldTemplate ):
322395 """Class that registers basic python types
323396
@@ -606,6 +679,9 @@ def recurse_generate(cls, spock_cls, builder_space: BuilderSpace):
606679 # References to tuner classes
607680 elif _is_spock_tune_instance (attribute .type ):
608681 handler = RegisterTuneCls ()
682+ # References to callables
683+ elif isinstance (attribute .type , _SpockVariadicGenericAlias ):
684+ handler = RegisterCallableField ()
609685 # Basic field
610686 else :
611687 handler = RegisterSimpleField ()
@@ -617,6 +693,9 @@ def recurse_generate(cls, spock_cls, builder_space: BuilderSpace):
617693 # error on instantiation
618694 try :
619695 spock_instance = spock_cls (** fields )
696+ # If there is a __post_hook__ dunder method then call it
697+ if hasattr (spock_cls , "__post_hook__" ):
698+ spock_instance .__post_hook__ ()
620699 except Exception as e :
621700 raise _SpockInstantiationError (
622701 f"Spock class `{ spock_cls .__name__ } ` could not be instantiated -- attrs message: { e } "
0 commit comments