hamilton icon indicating copy to clipboard operation
hamilton copied to clipboard

Modifications to enable decorating functions from another module

Open skrawcz opened this issue 3 years ago • 4 comments

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...

skrawcz avatar Oct 27 '22 17:10 skrawcz

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())

elijahbenizzy avatar Oct 31 '22 15:10 elijahbenizzy

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.

skrawcz avatar Jan 25 '23 01:01 skrawcz

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

skrawcz avatar Jan 27 '23 22:01 skrawcz

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...

elijahbenizzy avatar Jan 27 '23 23:01 elijahbenizzy