Skip to content

Conversation

@dmadisetti
Copy link
Collaborator

@dmadisetti dmadisetti commented Jul 25, 2025

📝 Summary

External functions are assumed to be pure. If an external function wraps a notebook function, then our test was unable to pick up the notebook change. This PR adds test to catch this behavior, and adds an appropriate fix (explicitly checking to see if the external function is used as a wrapper)

The PR also catches the general case of pickle not correctly capturing the transitive references of unhashable ContextExecution objects. This is a detectable edgecase with poorly defined behavior (by virtue of pickle). Future work should include adding a lint rule encouraging users away from this condition.

@dmadisetti dmadisetti added the bug Something isn't working label Jul 25, 2025
@vercel
Copy link

vercel bot commented Jul 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
marimo-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 26, 2025 1:11am

mscolnick
mscolnick previously approved these changes Jul 26, 2025
@dmadisetti
Copy link
Collaborator Author

@akshayka

@dmadisetti dmadisetti merged commit 236f8cd into main Jul 28, 2025
52 of 55 checks passed
@dmadisetti dmadisetti deleted the dm/wrap-poc branch July 28, 2025 21:59
@github-actions
Copy link

🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.14.14-dev35

dmadisetti added a commit that referenced this pull request Jul 30, 2025
dmadisetti added a commit that referenced this pull request Aug 1, 2025
## 📝 Summary

Bug initially mistaken to be caused from #5758 (happened to be observed
around the same time as that push)

Cache wrapping previously assumed that a context would be present with
all import and definitions defined.
Module lookup logic became stale after #5678

This PR fixes this issue and provides specific decorator tests. Fixes
internal demo, and previously observed behavior.
dmadisetti added a commit that referenced this pull request Aug 1, 2025
dmadisetti added a commit that referenced this pull request Aug 4, 2025
 (#5876)

## 📝 Summary

Restores #5758 with additional
tests. Broken into 2 PRs to make the diffs more evident.

 - The first PR is bulk revert
- the follow up PR (#5873) addresses reference dependency issues in an
external lib.
dmadisetti added a commit that referenced this pull request Aug 6, 2025
## 📝 Summary

Follow up to #5758

Solves reference dependency issues in an external lib, by creating a
partial graph of toplevel functions on invocation. Previously, the
"graph" of an external function was allowed to be blank. This is
incorrect, since both setup cell values, and other top level definitions
can be exposed to the cached function.

For example in tests/_save/external_decorators/transitive_wrappers_1.py

```python
with app.setup:
    ...
    impure_state = ...

@app.function
def my_impure_decorator(func):
    """An impure decorator that depends on impure_state"""

    @functools.wraps(func)
    def wrapper(*args: Any, **kwargs: Any):
        # Decorator depends on impure_state
        wrapper._value = ... # dependent on impure state ...
        return func(*args, **kwargs)

    return wrapper

...

@app.function
@my_impure_decorator
def pure_function():
    # This function itself is pure (no external dependencies)
    return 42

...
```

on `from external_decorators.transitive_wrappers_1 import pure_function`
a partial graph is constructed to invalidate pure_function based on its
relationship `pure_function` -> `impure_function` -> `impure_state`.
Whereas before, we just ignored these relationships because
`pure_function` was determined to be an external function and thus
'pure'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants