hamilton icon indicating copy to clipboard operation
hamilton copied to clipboard

Build with Local Function Directly

Open swapdewalkar opened this issue 1 year ago • 6 comments

--- PR TEMPLATE INSTRUCTIONS (1) ---

Address this Issue #685

Changes

  • Added a local builder helper.
  • Used python inspect to find out parent module and included with in sys modules.

How I tested this

Unit Tests

Notes

Checklist

  • [x] PR has an informative and human-readable title (this will be pulled into the release notes)
  • [x] Changes are limited to a single goal (no scope creep)
  • [x] Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
  • [x] Any change in functionality is tested
  • [x] New functions are documented (with a description, list of inputs, and expected output)
  • [x] Placeholder code is flagged / future TODOs are captured in comments
  • [x] Project documentation has been updated if adding/changing functionality.

swapdewalkar avatar Mar 28 '24 15:03 swapdewalkar

@swapdewalkar can you motivate this with an example please? I'm interested, curious to hear where/when you'd use it.

skrawcz avatar Mar 28 '24 18:03 skrawcz

@skrawcz I saw the requirement here to get all fns that are defined in the local module and insert them into a driver.

dr = driver.Builder()
      .with_local_modules()
      .build()

instead of

if __name__ == '__main__':
    import __main__
    dr = driver.Builder()
                     .with_modules(__main__)
                     .build()
    print(dr.execute(["foo"]))

Let me know if I understood something different from ticket.

swapdewalkar avatar Apr 01 '24 11:04 swapdewalkar

@swapdewalkar cool makes sense -- want to comment on that ticket so I can assign it to you?

Otherwise I think we just need a test to exercise this properly.

skrawcz avatar Apr 01 '24 17:04 skrawcz

@swapdewalkar thanks for the contribution!

The Python import system behaves in strange ways at times, so it would be beneficial if you could add to the docstring of .with_local_modules() a snippet of what Python code should be in your .py file and how to execute the code.

For instance, the current approach with inspect.stack()[1][0] seems to work for python -m run but will fail for python run.py of the same file. In that case, it can lead to hard to debug IndexError: list index out of range

A potential solution would be

def with_local_modules(self) -> "Builder":
    """Adds the local modules to the modules list.
    :return: self
    """
    module = __import__("__main__")
    self.modules.append(module)
    return self

This will get the module "__main__" from sys.modules and should be directly equivalent to

if __name__ == "__main__":
  import __main__

But I invite you to investigate and set the appropriate tests!

zilto avatar Apr 01 '24 22:04 zilto

I will add more tests!

swapdewalkar avatar Apr 02 '24 10:04 swapdewalkar

Just waiting on more tests for this one :)

skrawcz avatar Apr 22 '24 03:04 skrawcz