Skip to content

Commit

Permalink
[Bug] del f._self_call_placeholder_ even when calling f raises ex…
Browse files Browse the repository at this point in the history
…ception (#994)

Closes #993 -- subsequent calls of stateless-decorated functions return `Placeholder` after raising an exception
  • Loading branch information
hudson-ai authored Aug 28, 2024
1 parent 89c1482 commit 56a419a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
23 changes: 14 additions & 9 deletions guidance/_guidance.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,20 @@ def wrapped(*args, **kwargs):
if no_args:
f._self_call_placeholder_ = Placeholder()

# call the function to get the grammar node
node = f(_null_grammar, *args, **kwargs)
if not isinstance(node, (Terminal, str)):
node.name = f.__name__

# replace all the placeholders with our generated node
if no_args:
replace_grammar_node(node, f._self_call_placeholder_, node)
del f._self_call_placeholder_
try:
# call the function to get the grammar node
node = f(_null_grammar, *args, **kwargs)
except:
raise
else:
if not isinstance(node, (Terminal, str)):
node.name = f.__name__
# replace all the placeholders with our generated node
if no_args:
replace_grammar_node(node, f._self_call_placeholder_, node)
finally:
if no_args:
del f._self_call_placeholder_

return node

Expand Down
17 changes: 15 additions & 2 deletions tests/unit/test_decorator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import guidance
from guidance import gen, models
from guidance import gen

def test_dedent_basic():
"""Test that dedent functionality in f-strings works across Python versions."""
Expand Down Expand Up @@ -133,4 +134,16 @@ def inconsistent_indentation(lm):

# lm = guidance.models.Mock()
# result = lm + outer_function()
# assert result == "Inner function variable:\nouter_var: outer_value\n"
# assert result == "Inner function variable:\nouter_var: outer_value\n"

def test_exception_on_repeat_calls():
@guidance(stateless=True, dedent=False)
def raises(lm):
assert False
with pytest.raises(AssertionError):
raises()
with pytest.raises(AssertionError):
# Test against failure to reset the grammar function;
# improper handling may not raise and may instead return
# a Placeholder grammar node
raises()

0 comments on commit 56a419a

Please sign in to comment.