Skip to content

fix(types): exclude *args/**kwargs from the signature schema - #2048

Open
BlueX888 wants to merge 1 commit into
dottxt-ai:mainfrom
BlueX888:fix/prep-signature-varargs-required-fields
Open

BlueX888 wants to merge 1 commit into
dottxt-ai:mainfrom
BlueX888:fix/prep-signature-varargs-required-fields

Conversation

@BlueX888

Copy link
Copy Markdown

Summary

get_schema_from_signature now skips *args and **kwargs parameters instead of turning them into schema properties.

Why

get_schema_from_signature built a Pydantic model from every parameter in the signature, including the var-positional (*args) and var-keyword (**kwargs) ones (src/outlines/types/utils.py:199). Since such parameters have no default, they became required properties of the generated schema, even though they can never be bound by ** unpacking. This violates the invariant documented in the docstring (src/outlines/types/utils.py:193): every JSON object valid to the output schema must be passable to the function with **:

def fn(a: int, *args: str): ...

schema = get_schema_from_signature(fn)  # required: ["a", "args"]
fn(**{"a": 1, "args": "x"})           # TypeError: fn() got an unexpected keyword argument 'args'

When the function does have a **kwargs parameter to absorb them, the values silently land in **kwargs under their own names instead of the variadic parameters they represent.

Changes

  • src/outlines/types/utils.py: skip parameters whose kind is VAR_POSITIONAL or VAR_KEYWORD in get_schema_from_signature.
  • tests/types/test_types_utils.py: regression test test_get_schema_from_signature_ignores_var_parameters.

Testing

$ pytest tests/types/test_types_utils.py::test_get_schema_from_signature_ignores_var_parameters   # on main
FAILED ... AssertionError: assert ['a', 'args', 'b', 'kwargs'] == ['a', 'b']

$ pytest tests/types/test_types_utils.py::test_get_schema_from_signature_ignores_var_parameters   # with this fix
1 passed

$ pytest tests/types/
347 passed

$ pre-commit run --all-files
check for merge conflicts................................................Passed
debug statements (python)................................................Passed
fix end of files.........................................................Passed
trim trailing whitespace.................................................Passed
mypy.....................................................................Passed
ruff.....................................................................Passed

get_schema_from_signature treated *args and **kwargs parameters like
regular keyword arguments, so they became required properties of the
generated JSON Schema. Such parameters can never be bound via **
unpacking: passing a schema-valid object then raises "TypeError: got an
unexpected keyword argument" when the function has no **kwargs to
absorb them, and otherwise the values silently land in **kwargs under
their own names.

Skip parameters whose kind is VAR_POSITIONAL or VAR_KEYWORD, so every
JSON object valid to the schema can be passed to the function with **,
as the docstring promises.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant