fix: compare inspect sentinels by identity in function_schema - #3961
Merged
seratch merged 2 commits intoJul 27, 2026
Conversation
function_schema compared parameter defaults and annotations to inspect._empty
with == and !=, invoking the user value's __eq__. A default with elementwise
equality, such as a numpy array, crashes schema creation at decoration time
("The truth value of an array with more than one element is ambiguous"), and
a default whose __eq__ answers True is mistaken for the no-default sentinel,
silently marking the parameter required and discarding the default.
Use identity checks for all five sentinel comparisons, per the inspect
module's documented convention (param.default is Parameter.empty). Python
identifiers cannot shadow the sentinel, so this is behavior-preserving for
every value without a pathological __eq__.
seratch
requested changes
Jul 26, 2026
seratch
left a comment
Member
There was a problem hiding this comment.
Can you run make typecheck and resolve the errors?
Running make mypy and make pyright in parallel...
make[1]: Entering directory '/home/runner/work/openai-agents-python/openai-agents-python'
uv run mypy . --exclude site
make[1]: Entering directory '/home/runner/work/openai-agents-python/openai-agents-python'
uv run pyright --project pyrightconfig.json
0 errors, 0 warnings, 0 informations
WARNING: there is a new pyright version available (v1.1.408 -> v1.1.411).
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
make[1]: Leaving directory '/home/runner/work/openai-agents-python/openai-agents-python'
tests/test_function_schema.py:1072: error: Return type "_ElementwiseEqual" of "__eq__" incompatible with return type "bool" in supertype "builtins.object" [override]
tests/test_function_schema.py:1075: error: Return type "_ElementwiseEqual" of "__ne__" incompatible with return type "bool" in supertype "builtins.object" [override]
Found 2 errors in 1 file (checked 832 source files)
make[1]: *** [Makefile:24: mypy] Error 1
make[1]: Leaving directory '/home/runner/work/openai-agents-python/openai-agents-python'
make: *** [Makefile:32: typecheck] Error 2
The elementwise-equality stub returned its own type from __eq__ and __ne__, which mypy rejects as an incompatible override of object. Annotate the return as Any, matching how numpy's stubs type elementwise comparison.
auto-merge was automatically disabled
July 26, 2026 23:32
Head branch was pushed to by a user without write access
Contributor
Author
|
Fixed in 3de52d1, which crossed with your review by a few minutes. The stub's |
seratch
approved these changes
Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
function_schemacompares parameter defaults (and annotations) toinspect._emptywith==/!=, which invokes the user-supplied value's__eq__. Two observable failures on valid Python functions:Crash at decoration time — a default with elementwise equality semantics (a numpy array is the canonical case) makes
default != inspect._emptyreturn an array, whose truthiness raises:Verified with real numpy; the regression test uses a dependency-free stub with the same
__eq__shape.Silent contract violation — a default whose
__eq__answersTrue(mocks, sentinels, some DSL objects) satisfiesdefault == inspect._empty, so the parameter is marked required in the schema and its default silently discarded.The
inspectmodule's documented convention is identity comparison (param.default is Parameter.empty); the sentinel is a unique object precisely so user values can never influence the check. This PR switches all five sentinel comparisons in the file tois/is not— the two default checks above (the observable bugs) and the three annotation checks, which carry the same latent hazard. Identity is behavior-preserving for every value without a pathological__eq__.Test plan
__eq__default must build a schema, stay optional, and round-trip throughto_call_args; an always-True-__eq__default must not be marked required. Both fail onmainand pass with the fix.make format,make lint,make typecheck,make testsall pass.Issue number
None — found by reading
function_schema.py(same pass that produced #3956).Checks
.agents/skills/code-change-verification/scripts/run.sh/reviewbefore submitting this PR