Jernj Frank
09/12/2024, 7:10 PMJernj Frank
09/12/2024, 7:11 PMThierry Jean
09/12/2024, 7:19 PM.with_modules(foo, bar, allow_override=True) might not equal .with_modules(bar, foo, allow_override=True). It's good to use the flag allow_override to prevent users accidentally overriding functions though
Since this change involves many core internals (FunctionGraph, Driver , Builder) I'm wondering if there are other ways to support this feature. Hamilton couples a lot of thing to the module Python construct (for better or worse). But concretely, the issue seems to be overriding functions. It might be a valuable change to catch duplicate functions "closer to the user" (e.g., Builder.build() rather than in internal components like FunctionGraphJernj Frank
09/12/2024, 7:40 PMfind_functions() all the way from graph.py and move it to the Builder? Or do you propose to double check and pre-prepare the functions before they get passed to the create_function_graph?
There is another entry point by creating the Driver directly without using the Builder - not sure how many people use it this way, but one of the first examples on the website does that. I don't think we can only push it onto the task of the Builder .Thierry Jean
09/12/2024, 7:50 PMfind_functions() , which is a public-facing API part of hamilton.graph_utils. Ideally, it would allow us to only make "surface level" changes closer to the Builder.
## Default behavior
We can keep .with_modules() as-is and avoid changes to other internals (Driver, FunctionGraph). This ensures safety for all Hamilton users
## Override behavior
When specifying .with_modules(..., allow_overrides=True),
the logic of .with_modules() could directly call find_functions() and dynamically removed duplicate functions
def with_modules(*modules):
if allow_overrides:
functions_seen = set()
for module in modules:
functions = graph_utils.find_functions(module)
for name, callabl in functions:
if name in functions_seen
del getattr(module, name)
else:
functions_seen.add(name)
self.modules.extend(modules)Thierry Jean
09/12/2024, 7:53 PMimport foo
import bar
dr = Builder().with_modules(foo, bar, allow_overrides=True).build()
# works because loaded first
foo.my_func()
# error because the function is deleted
bar.my_func()Thierry Jean
09/12/2024, 7:58 PMmodule
def with_modules(*modules):
if allow_overrides:
functions_seen = set()
temp_modules = []
for module in modules:
unique_functions = set()
functions = graph_utils.find_functions(module)
for name, callabl in functions:
if name in functions_seen
del getattr(module, name)
else:
unique_functions.add(callabl)
functions_seen.add(name)
temp_module = hamilton.ad_hoc_utils.create_temporary_module(...)
temp_modules.append(temp_module)
self.modules.extend(modules)Elijah Ben Izzy
09/12/2024, 8:02 PMallow_overrides flag — we specifically decided to put it centrally, rather than on the with_modules due to the fact that it gets you to odd behavior if it’s on an individual module call. E.G. what if you add it in one with_modules and not the other? More stuff to think about.
We also can’t catch it on the builder @Thierry Jean — it has no idea what the nodes are, as we construct the fnction graph. We could always rearchictect (construct the function graph beforehand then merge a bunch), but given the way it’s built, I think this is a very reasonable approach. Function graph is specifically repsonsible for taking all the functions and putting it together. Some nuance in how we handle it with modules/functions/who knows about what, but that’s all stuff that can change because it’s an internal API. The more we push out, the harder of a time we have doing that later.Elijah Ben Izzy
09/12/2024, 8:05 PMElijah Ben Izzy
09/12/2024, 8:22 PMsphinx-autobuild -b dirhtml -W -E -T --watch docs/ -a docs /tmp/mydocs.
Might also be nice to add a note here (linking out to the prior one): https://hamilton.dagworks.io/en/latest/concepts/builder/ on this capability.
RST can be an absolute mess (linking/compiling), so ping if you have trouble. You can probably get away just iterating ont he PR after it builds (although I’m not sure if I have to run it or it always will)Jernj Frank
09/12/2024, 9:01 PMElijah Ben Izzy
09/12/2024, 9:12 PM