Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(function_schema): add enforce_type_annotations flag for stricter schema validation with type enforcement, clearer errors, and updated docstrings#1092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
mshsheikh wants to merge5 commits intoopenai:main
base:main
Choose a base branch
Loading
frommshsheikh:patch-8

Conversation

mshsheikh
Copy link
Contributor

Problem:
Previously, thefunction_schema function silently defaulted unannotated parameters toAny, leading to:

  • Ambiguous JSON schemas ("type": "any")
  • Potential runtime errors due to invalid inputs
  • Reduced reliability of LLM tool calls This made it harder to ensure type safety without manual validation.

Solution:

This PR introduces theenforce_type_annotations flag tofunction_schema, allowing developers to:

  1. Enforce type annotations by settingenforce_type_annotations=True, which raises aValueError for unannotated parameters.
  2. Maintain backward compatibility by defaulting toAny whenenforce_type_annotations=False (default).

Example error message:

raiseValueError(f"Parameter '{name}' must be type-annotated. Example: def func({name}: str)")

Changes Made

  1. New Parameter:
deffunction_schema(func:Callable[...,Any],enforce_type_annotations:bool=False,# New parameter       ...   ):
  1. Validation Logic:
  • Ifenforce_type_annotations=True, unannotated parameters now raise aValueError with a clear example.
  • Falls back toAny if disabled (default behavior preserved).
  1. Docstring Updates:
  • Added detailed documentation forenforce_type_annotations:
Args:enforce_type_annotations:IfTrue,raisesaValueErrorforanyunannotatedparameters.IfFalse (default),unannotatedparametersareassumedtobeof type`Any`.
  1. Error Message Improvements:
  • Clear guidance for developers:Example: def func(x: str)

Backward Compatibility:

  • Preserved: Existing code continues to work as-is (defaultenforce_type_annotations=False).
  • Opt-in: Type annotation enforcement is optional, allowing gradual adoption.

Testing Guidance:
To verify the change:

deftest_enforce_type_annotations():deffunc(x): ...withpytest.raises(ValueError):function_schema(func,enforce_type_annotations=True)# Should not raisefunction_schema(func,enforce_type_annotations=False)

Impact:

  • Type Safety: Prevents ambiguous schemas and improves LLM tool reliability.
  • Developer Experience: Clear error messages guide users to fix missing annotations.
  • Flexibility: Maintains backward compatibility while enabling stricter validation.

Example Usage:

# Strict mode: raises error for unannotated paramsschema=function_schema(my_func,enforce_type_annotations=True)# Default mode: works as beforeschema=function_schema(my_func)# silently defaults to Any

… schema validation with type enforcement, clearer errors, and updated docstringsProblem:Previously, the `function_schema` function silently defaulted unannotated parameters to `Any`, leading to:- Ambiguous JSON schemas (`"type": "any"`)- Potential runtime errors due to invalid inputs- Reduced reliability of LLM tool callsThis made it harder to ensure type safety without manual validation.Solution:This PR introduces the `enforce_type_annotations` flag to `function_schema`, allowing developers to:1. Enforce type annotations by setting `enforce_type_annotations=True`, which raises a `ValueError` for unannotated parameters.2. Maintain backward compatibility by defaulting to `Any` when `enforce_type_annotations=False` (default).Example error message:```pythonraise ValueError(    f"Parameter '{name}' must be type-annotated. Example: def func({name}: str)")```Changes Made1. New Parameter:```python   def function_schema(       func: Callable[..., Any],       enforce_type_annotations: bool = False,  # New parameter       ...   ):```2. Validation Logic:- If `enforce_type_annotations=True`, unannotated parameters now raise a `ValueError` with a clear example.- Falls back to `Any` if disabled (default behavior preserved).3. Docstring Updates:- Added detailed documentation for `enforce_type_annotations`:```python     Args:         enforce_type_annotations: If True, raises a ValueError for any unannotated parameters.             If False (default), unannotated parameters are assumed to be of type `Any`.```4. Error Message Improvements:- Clear guidance for developers:`Example: def func(x: str)`Backward Compatibility:- Preserved: Existing code continues to work as-is (default `enforce_type_annotations=False`).- Opt-in: Type annotation enforcement is optional, allowing gradual adoption.Testing Guidance:To verify the change:```pythondef test_enforce_type_annotations():    def func(x): ...    with pytest.raises(ValueError):        function_schema(func, enforce_type_annotations=True)    # Should not raise    function_schema(func, enforce_type_annotations=False)```Impact:- Type Safety: Prevents ambiguous schemas and improves LLM tool reliability.- Developer Experience: Clear error messages guide users to fix missing annotations.- Flexibility: Maintains backward compatibility while enabling stricter validation.Example Usage:```python# Strict mode: raises error for unannotated paramsschema = function_schema(my_func, enforce_type_annotations=True)# Default mode: works as beforeschema = function_schema(my_func)  # silently defaults to Any```
@seratchseratch added enhancementNew feature or request feature:core labelsJul 14, 2025
Copy link
Member

@seratchseratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

having unit tests would be appreciated too

@@ -186,6 +186,7 @@ def generate_func_documentation(

deffunction_schema(
func:Callable[...,Any],
enforce_type_annotations:bool=False,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

adding this option may be a good one, but adding here (=2nd arg) is a breaking change. new arguments must be added as the last one when a method accepts both args and keyword args.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks for the feedback! You're absolutely right, the enforce_type_annotations parameter has been moved to the end of the argument list in the latest update to preserve backward compatibility.

@mshsheikhmshsheikh requested a review fromseratchJuly 14, 2025 15:05
Adds a new enforce_type_annotations flag to function_schema to improve type safety:- When enabled (True): Raises an error for unannotated parameters (e.g., def func(x): ...).- When disabled (False): Falls back to Any (default behavior remains unchanged).- Backward compatibility: Positional arguments still work (e.g., function_schema(my_func, "sphinx")).Example Error Message:Parameter 'x' must be type-annotated. Example: def func(x: str)Test Coverage:https://github.com/openai/openai-agents-python/blob/main/tests/test_function_schema.py
@mshsheikh
Copy link
ContributorAuthor

having unit tests would be appreciated too

@seratch
Unit tests have been added to validate theenforce_type_annotations behavior, including:

  • Enforcement of type hints (True/False cases)
  • Fallback toAny when disabled
  • Backward compatibility with positional args

Tests are here:

Adds a new enforce_type_annotations flag to function_schema to improve type safety:- When enabled (True): Raises an error for unannotated parameters (e.g., def func(x): ...).- When disabled (False): Falls back to Any (default behavior remains unchanged).- Backward compatibility: Positional arguments still work (e.g., function_schema(my_func, "sphinx")).Example Error Message:Parameter 'x' must be type-annotated. Example: def func(x: str)Test Coverage:https://github.com/openai/openai-agents-python/blob/main/tests/test_function_schema.py
Copy link
Member

@seratchseratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

this looks good to me, but@rm-openai if you have a different opinion, please share it

@seratchseratch requested a review fromrm-openaiJuly 15, 2025 03:48
Copy link
Collaborator

@rm-openairm-openai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

My general stance is to be careful about adding new options/settings bc each one makes it that much harder to understand the code. In this case, my thought is -- not using types is your choice, why would someone not use type annotations but also use enforce_type_annotations?

@mshsheikh
Copy link
ContributorAuthor

My general stance is to be careful about adding new options/settings bc each one makes it that much harder to understand the code. In this case, my thought is -- not using types is your choice, why would someone not use type annotations but also use enforce_type_annotations?

Thank you for the thoughtful feedback! The enforce_type_annotations flag is designed as an opt-in tool for teams gradually adopting type safety, not a default requirement. This allows:

  • Progressive enforcement : New code can opt into stricter validation without breaking legacy functions.
  • Explicit error prevention : Catches unannotated parameters early, reducing ambiguous schemas and runtime issues.
    The default (False) preserves backward compatibility, minimizing overhead for existing users.
    Would this approach address your concerns while balancing flexibility and safety?

@mshsheikh
Copy link
ContributorAuthor

Thanks for the thorough feedback@seratch and@rm-openai!
The latest changes address the positional argument issue and include comprehensive tests. I’ve also revised the flag’s documentation to clarify its purpose as an opt-in tool for stricter validation. Let me know if further adjustments are needed!

Key Updates:

  • enforce_type_annotations added as the last parameter to avoid breaking existing usage.
  • Tests validate enforcement, fallback behavior, and backward compatibility.
  • Error messages include actionable examples for developers.

This balances flexibility and safety while respecting existing workflows. Let me know your thoughts!

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@seratchseratchseratch approved these changes

@rm-openairm-openaiAwaiting requested review from rm-openai

Requested changes must be addressed to merge this pull request.

Assignees
No one assigned
Labels
enhancementNew feature or requestfeature:core
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@mshsheikh@seratch@rm-openai

[8]ページ先頭

©2009-2025 Movatter.jp