Modifications to enable decorating functions from another module
If the user wants to reuse hamilton functions without hamilton, this commit shows one way to do it -- and what would be required on Hamilton's side to support it.
Basically we'd need a convention. Not sure it's a good idea. Probably easier to instead have boilerplate code people use to try/except the import if hamilton does not exist and have the decorators be identity functions...
I like my (somewhat hacky) approach more -- what you suggested above. This is easy, can be copy/pasted anywhere, and doesn't require a framework change:
class mock_modifier:
def __getattr__(self, attr):
return self
def __call__(*args, **kwargs):
def identity(fn):
return fn
return identity
try:
from hamilton import function_modifiers
except ImportError as e:
print('Cannot import hamilton, using a mock function modifier')
function_modifiers = mock_modifier()
@function_modifiers.config.when(foo=1)
def bar() -> int:
return 1
@function_modifiers.extract_fields({'a' : int, 'b' : int})
def baz() -> dict:
return {'a' : 1, 'b' : 1}
if __name__ == '__main__':
print(bar())
print(baz())
another idea I had, was to have a dummy python module that one could import e.g. sf-hamilton-no-op ... and it would have 0 dependencies and just ensure that decorators did nothing basically.
I like my (somewhat hacky) approach more -- what you suggested above. This is easy, can be copy/pasted anywhere, and doesn't require a framework change:
class mock_modifier: def __getattr__(self, attr): return self def __call__(*args, **kwargs): def identity(fn): return fn return identity try: from hamilton import function_modifiers except ImportError as e: print('Cannot import hamilton, using a mock function modifier') function_modifiers = mock_modifier() @function_modifiers.config.when(foo=1) def bar() -> int: return 1 @function_modifiers.extract_fields({'a' : int, 'b' : int}) def baz() -> dict: return {'a' : 1, 'b' : 1} if __name__ == '__main__': print(bar()) print(baz())
would this work for the case someone imports from the module? It wouldn't right? E.g.
from hamilton.function_modifiers import config
I like my (somewhat hacky) approach more -- what you suggested above. This is easy, can be copy/pasted anywhere, and doesn't require a framework change:
class mock_modifier: def __getattr__(self, attr): return self def __call__(*args, **kwargs): def identity(fn): return fn return identity try: from hamilton import function_modifiers except ImportError as e: print('Cannot import hamilton, using a mock function modifier') function_modifiers = mock_modifier() @function_modifiers.config.when(foo=1) def bar() -> int: return 1 @function_modifiers.extract_fields({'a' : int, 'b' : int}) def baz() -> dict: return {'a' : 1, 'b' : 1} if __name__ == '__main__': print(bar()) print(baz())would this work for the case someone imports from the module? It wouldn't right? E.g.
from hamilton.function_modifiers import config
Yeah it would have to be adjusted...