Skip to content

✅ Add tests for nullable parameters and defaults#14829

Draft
YuriiMotov wants to merge 11 commits intomasterfrom
add-tests-for-parameter-defaults
Draft

✅ Add tests for nullable parameters and defaults#14829
YuriiMotov wants to merge 11 commits intomasterfrom
add-tests-for-parameter-defaults

Conversation

@YuriiMotov
Copy link
Member

@YuriiMotov YuriiMotov commented Feb 5, 2026

Description

There are currently several issues around nullable parameters and parameters with defaults:

  • inability to distinguish explicitly passed values from defaults (if no value received, the default value is passed to parameter validator)
  • parameters declared as Pydantic model behave different from non-model parameters (different behavior and error messages)
    • empty strings are not replaced by None for Form parameters declared as Pydantic model - this leads to validation error for optional int parameter when empty string is submitted
    • title of Header parameters contains hyphens for non-model parameters (for model parameters hyphens are replaced by whitespaces)
    • for Header parameters declared as Pydantic model, field names use underscore instead of hyphens in error response
    • null values are treated as missing value for non-Model Body parameters
    • missing or invalid body value results in different errors for parameters declared as Body model and parameters declared as several Body parameters
  • if the default value is None, it's not reflected in schema
  • Handling of empty strings for Form parameters

doesn’t seem to work correctly - None values are then being dropped. So, it’s equal to not providing the value. But people want to be able to distinguish between no value and explicitly passed empty string (ecplicit None for nullable parameter)

  • null-value body is treated as missing (it’s valid body in latest specs)
  • It’s possible to specify default value for bytes File parameter, but it doesn’t work (raises AttributeError as FastAPI attempts to use it as file object)

This PR is intended to expose these issues for different types of parameters.

Tests structure

Tests for each type of parameter (Query, Form, Body, etc..) in general follow the pattern:

  • For different default values ( 1 - without default value (nullable required); 2 - default is None (optional); 3 - default is not None):
    • Tests for: non-model parameters and parameters declared as Pydantic model (for Body also have single parameters with embed=False)
      • Declare parameters with different field types (all nullable): str, int, list[int]
      • Test:
        • openapi schema
        • request with missing parameter values (and with missing body in case of Body)
        • request with explicit null values (and with null-body in case of Body) when it's possibe
        • request with non-default value
      • In tests check:
        • Data passed to field validator is as expected (checked using BeforeValidator). Also check fields_set for parameters declared as model
        • Schema and error messages are correct and equal in case of parameters declared as model and non-model parameters
        • Values after validation are correct

Open questions

  • Should we prohibit default value for File parameters? I can't come up with use case when it might be needed. And it doesn't work currently
  • For Form fields, how should we treat the empty string values?

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 5, 2026

Merging this PR will not alter performance

✅ 20 untouched benchmarks


Comparing add-tests-for-parameter-defaults (7fed267) with master (0e68d36)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (64d0ee9) during the generation of this report, so 0e68d36 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

"type": "missing",
"loc": ["body", "int_val"],
"msg": "Field required",
"input": IsOneOf(None, {}),
Copy link
Member Author

Choose a reason for hiding this comment

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

I think ideally we should fix this as well - make parameters declared as model and non-model parameters return the same value. And, it should be probably {}.
This will likely be fixed as a side effect if we address all other issues

"file": {
"title": "File",
"anyOf": [{"type": "string", "format": "binary"}, {"type": "null"}],
"default": "default", # <= Default value for file looks strange to me
Copy link
Member Author

Choose a reason for hiding this comment

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

Suggested change
"default": "default", # <= Default value for file looks strange to me
"default": "default",

Does it make sense to have default value for File field?

@YuriiMotov YuriiMotov marked this pull request as ready for review February 6, 2026 16:00
@YuriiMotov YuriiMotov marked this pull request as draft February 8, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant