| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,13 +71,8 @@ | |||
| 71 | 71 | from starlette.requests import HTTPConnection, Request | |
| 72 | 72 | from starlette.responses import Response | |
| 73 | 73 | from starlette.websockets import WebSocket | |
| 74 | - from typing_extensions import Annotated, get_args, get_origin | ||
| 75 | - | ||
| 76 | - try: | ||
| 77 | - from typing_extensions import TypeAliasType | ||
| 78 | - except ImportError: # pragma: no cover | ||
| 79 | - TypeAliasType = None # type: ignore[misc,assignment] | ||
| 80 | - | ||
| 74 | + from typing_extensions import get_args, get_origin | ||
| 75 | + from typing_inspection.introspection import AnnotationSource, inspect_annotation | ||
| 81 | 76 | ||
| 82 | 77 | multipart_not_installed_error = ( | |
| 83 | 78 | 'Form data requires "python-multipart" to be installed. \n' | |
@@ -360,22 +355,22 @@ def analyze_param( | |||
| 360 | 355 | ) -> ParamDetails: | |
| 361 | 356 | field_info = None | |
| 362 | 357 | depends = None | |
| 363 | - type_annotation: Any = Any | ||
| 364 | - use_annotation: Any = Any | ||
| 365 | - if TypeAliasType is not None and isinstance(annotation, TypeAliasType): | ||
| 366 | - # unpack in case py3.12 type syntax is used | ||
| 367 | - annotation = annotation.__value__ | ||
| 358 | + type: Any = Any | ||
| 359 | + meta: list[Any] = [] | ||
| 368 | 360 | if annotation is not inspect.Signature.empty: | |
| 369 | - use_annotation = annotation | ||
| 370 | - type_annotation = annotation | ||
| 361 | + inspected = inspect_annotation( | ||
| 362 | + annotation, | ||
| 363 | + annotation_source=AnnotationSource.BARE, | ||
| 364 | + unpack_type_aliases="lenient", | ||
| 365 | + ) | ||
| 366 | + meta = inspected.metadata | ||
| 367 | + type = inspected.type | ||
| 368 | + else: | ||
| 369 | + annotation = Any | ||
| 371 | 370 | # Extract Annotated info | |
| 372 | - if get_origin(use_annotation) is Annotated: | ||
| 373 | - annotated_args = get_args(annotation) | ||
| 374 | - type_annotation = annotated_args[0] | ||
| 371 | + if meta: | ||
| 375 | 372 | fastapi_annotations = [ | |
| 376 | - arg | ||
| 377 | - for arg in annotated_args[1:] | ||
| 378 | - if isinstance(arg, (FieldInfo, params.Depends)) | ||
| 373 | + arg for arg in meta if isinstance(arg, (FieldInfo, params.Depends)) | ||
| 379 | 374 | ] | |
| 380 | 375 | fastapi_specific_annotations = [ | |
| 381 | 376 | arg | |
@@ -392,7 +387,7 @@ def analyze_param( | |||
| 392 | 387 | if isinstance(fastapi_annotation, FieldInfo): | |
| 393 | 388 | # Copy `field_info` because we mutate `field_info.default` below. | |
| 394 | 389 | field_info = copy_field_info( | |
| 395 | - field_info=fastapi_annotation, annotation=use_annotation | ||
| 390 | + field_info=fastapi_annotation, annotation=annotation | ||
| 396 | 391 | ) | |
| 397 | 392 | assert ( | |
| 398 | 393 | field_info.default is Undefined or field_info.default is RequiredParam | |
@@ -427,17 +422,17 @@ def analyze_param( | |||
| 427 | 422 | ) | |
| 428 | 423 | field_info = value | |
| 429 | 424 | if PYDANTIC_V2: | |
| 430 | - field_info.annotation = type_annotation | ||
| 425 | + field_info.annotation = type | ||
| 431 | 426 | ||
| 432 | 427 | # Get Depends from type annotation | |
| 433 | 428 | if depends is not None and depends.dependency is None: | |
| 434 | 429 | # Copy `depends` before mutating it | |
| 435 | 430 | depends = copy(depends) | |
| 436 | - depends.dependency = type_annotation | ||
| 431 | + depends.dependency = type | ||
| 437 | 432 | ||
| 438 | 433 | # Handle non-param type annotations like Request | |
| 439 | 434 | if lenient_issubclass( | |
| 440 | - type_annotation, | ||
| 435 | + type, | ||
| 441 | 436 | ( | |
| 442 | 437 | Request, | |
| 443 | 438 | WebSocket, | |
@@ -447,9 +442,9 @@ def analyze_param( | |||
| 447 | 442 | SecurityScopes, | |
| 448 | 443 | ), | |
| 449 | 444 | ): | |
| 450 | - assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}" | ||
| 445 | + assert depends is None, f"Cannot specify `Depends` for type {type!r}" | ||
| 451 | 446 | assert field_info is None, ( | |
| 452 | - f"Cannot specify FastAPI annotation for type {type_annotation!r}" | ||
| 447 | + f"Cannot specify FastAPI annotation for type {type!r}" | ||
| 453 | 448 | ) | |
| 454 | 449 | # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value | |
| 455 | 450 | elif field_info is None and depends is None: | |
@@ -458,15 +453,15 @@ def analyze_param( | |||
| 458 | 453 | # We might check here that `default_value is RequiredParam`, but the fact is that the same | |
| 459 | 454 | # parameter might sometimes be a path parameter and sometimes not. See | |
| 460 | 455 | # `tests/test_infer_param_optionality.py` for an example. | |
| 461 | - field_info = params.Path(annotation=use_annotation) | ||
| 456 | + field_info = params.Path(annotation=annotation) | ||
| 462 | 457 | elif is_uploadfile_or_nonable_uploadfile_annotation( | |
| 463 | - type_annotation | ||
| 464 | - ) or is_uploadfile_sequence_annotation(type_annotation): | ||
| 465 | - field_info = params.File(annotation=use_annotation, default=default_value) | ||
| 466 | - elif not field_annotation_is_scalar(annotation=type_annotation): | ||
| 467 | - field_info = params.Body(annotation=use_annotation, default=default_value) | ||
| 458 | + type | ||
| 459 | + ) or is_uploadfile_sequence_annotation(type): | ||
| 460 | + field_info = params.File(annotation=annotation, default=default_value) | ||
| 461 | + elif not field_annotation_is_scalar(annotation=type): | ||
| 462 | + field_info = params.Body(annotation=annotation, default=default_value) | ||
| 468 | 463 | else: | |
| 469 | - field_info = params.Query(annotation=use_annotation, default=default_value) | ||
| 464 | + field_info = params.Query(annotation=annotation, default=default_value) | ||
| 470 | 465 | ||
| 471 | 466 | field = None | |
| 472 | 467 | # It's a field_info, not a dependency | |
@@ -483,7 +478,7 @@ def analyze_param( | |||
| 483 | 478 | ): | |
| 484 | 479 | field_info.in_ = params.ParamTypes.query | |
| 485 | 480 | use_annotation_from_field_info = get_annotation_from_field_info( | |
| 486 | - use_annotation, | ||
| 481 | + annotation, | ||
| 487 | 482 | field_info, | |
| 488 | 483 | param_name, | |
| 489 | 484 | ) | |
@@ -517,7 +512,7 @@ def analyze_param( | |||
| 517 | 512 | ) | |
| 518 | 513 | ) | |
| 519 | 514 | ||
| 520 | - return ParamDetails(type_annotation=type_annotation, depends=depends, field=field) | ||
| 515 | + return ParamDetails(type_annotation=type, depends=depends, field=field) | ||
| 521 | 516 | ||
| 522 | 517 | ||
| 523 | 518 | def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,6 +46,7 @@ dependencies = [ | |||
| 46 | 46 | "starlette>=0.40.0,<0.48.0", | |
| 47 | 47 | "pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0", | |
| 48 | 48 | "typing-extensions>=4.8.0", | |
| 49 | + "typing-inspection>=0.4.1", | ||
| 49 | 50 | ] | |
| 50 | 51 | ||
| 51 | 52 | [project.urls] | |
| Back | FazBrowse Home | New Git URL |
0 commit comments