Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆ Upgrade version required of Starlette from 0.19.1 to 0.20.4 #4820

Merged
merged 34 commits into from Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e5c9343
Bump starlette from 0.17.1 to 0.18.0
Kludex Jan 26, 2022
8d10fca
Fix linter
Kludex Jan 26, 2022
7331e08
Fix mypy
Kludex Jan 26, 2022
fb2fdf5
Remove unused Optional import
Kludex Jan 26, 2022
c096ac6
Bump starlette from 0.18.0 to 0.19.0
Kludex Jan 27, 2022
a96de7f
Add starlette master branch
Kludex Jan 27, 2022
cc64170
Undo some changes
Kludex Jan 27, 2022
03b0d4c
Add version on egg
Kludex Jan 27, 2022
facb6d8
Try with only link
Kludex Jan 27, 2022
a659c2b
Add starlette back
Kludex Jan 27, 2022
4305a0c
Remove HTTPException
Kludex Jan 27, 2022
b19e848
Add noqa on reimport
Kludex Jan 27, 2022
1b3342b
Empty commit
Kludex Jan 28, 2022
09c70c4
Update pyproject.toml
Kludex Jan 30, 2022
880dd0d
Update pyproject.toml
Kludex Jan 31, 2022
c48a399
Update pyproject.toml
Kludex Feb 1, 2022
7b519b8
Update pyproject.toml
Kludex Feb 1, 2022
d382aa5
Ignore WSGIMiddleware deprecation warning on tests
Kludex Mar 16, 2022
f6b410f
Bump starlette from 0.19.0 to 0.19.1
Kludex Apr 24, 2022
a22f960
Merge remote-tracking branch 'origin/master' into bump/starlette-0.19.1
Kludex Apr 24, 2022
755bdcd
Bump starlette from 0.19.1 to 0.20.0
Kludex Apr 24, 2022
f804228
Fix issues
Kludex Apr 24, 2022
e8cf7ff
Merge branch 'bump/starlette-0.19.1' into bump/starlette-0.20.0
Kludex Apr 24, 2022
8e3d62f
Drop Python 3.6
Kludex Apr 24, 2022
7a7771d
Update pyproject.toml
Kludex May 3, 2022
cde78fe
Merge branch 'master' into bump/starlette-0.20.0
Kludex May 3, 2022
f0b1323
Merge branch 'master' into bump/starlette-0.20.0
Kludex May 29, 2022
8fb8762
Update fastapi/exceptions.py
Kludex May 29, 2022
0878301
Update pyproject.toml
Kludex May 29, 2022
07d064b
🔀 Merge master
tiangolo Sep 15, 2022
d216a83
🔥 Remove unnecessary comment about Python 3.6, now deprecated
tiangolo Sep 15, 2022
a682496
⬆️ Upgrade Starlette version to 0.20.4
tiangolo Sep 15, 2022
6f4b956
🐛 Import ExceptionMiddleware from new location in Starlette
tiangolo Sep 15, 2022
339bd28
🎨 Fix type annotation from improved types in Starlette
tiangolo Sep 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
fail-fast: false

steps:
Expand Down
20 changes: 14 additions & 6 deletions fastapi/applications.py
@@ -1,5 +1,16 @@
from enum import Enum
from typing import Any, Callable, Coroutine, Dict, List, Optional, Sequence, Type, Union
from typing import (
Any,
Awaitable,
Callable,
Coroutine,
Dict,
List,
Optional,
Sequence,
Type,
Union,
)

from fastapi import routing
from fastapi.datastructures import Default, DefaultPlaceholder
Expand Down Expand Up @@ -121,11 +132,8 @@ def __init__(
generate_unique_id_function=generate_unique_id_function,
)
self.exception_handlers: Dict[
Union[int, Type[Exception]],
Callable[[Request, Any], Coroutine[Any, Any, Response]],
] = (
{} if exception_handlers is None else dict(exception_handlers)
)
Any, Callable[[Request, Any], Union[Response, Awaitable[Response]]]
] = ({} if exception_handlers is None else dict(exception_handlers))
self.exception_handlers.setdefault(HTTPException, http_exception_handler)
self.exception_handlers.setdefault(
RequestValidationError, request_validation_exception_handler
Expand Down
2 changes: 1 addition & 1 deletion fastapi/concurrency.py
Expand Up @@ -25,7 +25,7 @@ async def contextmanager_in_threadpool(
try:
yield await run_in_threadpool(cm.__enter__)
except Exception as e:
ok = await run_in_threadpool(cm.__exit__, type(e), e, None)
ok: bool = await run_in_threadpool(cm.__exit__, type(e), e, None)
if not ok:
raise e
else:
Expand Down
11 changes: 4 additions & 7 deletions fastapi/dependencies/utils.py
Expand Up @@ -462,13 +462,10 @@ async def solve_dependencies(
]:
values: Dict[str, Any] = {}
errors: List[ErrorWrapper] = []
response = response or Response(
content=None,
status_code=None, # type: ignore
headers=None, # type: ignore # in Starlette
media_type=None, # type: ignore # in Starlette
background=None, # type: ignore # in Starlette
)
if response is None:
response = Response()
del response.headers["content-length"]
response.status_code = None # type: ignore
dependency_cache = dependency_cache or {}
sub_dependant: Dependant
for sub_dependant in dependant.dependencies:
Expand Down
16 changes: 2 additions & 14 deletions fastapi/exceptions.py
@@ -1,20 +1,8 @@
from typing import Any, Dict, Optional, Sequence, Type
from typing import Any, Sequence, Type
Kludex marked this conversation as resolved.
Show resolved Hide resolved

from pydantic import BaseModel, ValidationError, create_model
from pydantic.error_wrappers import ErrorList
from starlette.exceptions import HTTPException as StarletteHTTPException


class HTTPException(StarletteHTTPException):
def __init__(
self,
status_code: int,
detail: Any = None,
headers: Optional[Dict[str, Any]] = None,
) -> None:
super().__init__(status_code=status_code, detail=detail)
self.headers = headers

from starlette.exceptions import HTTPException as HTTPException # noqa

RequestErrorModel: Type[BaseModel] = create_model("Request")
WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
Expand Down
12 changes: 6 additions & 6 deletions fastapi/routing.py
Expand Up @@ -127,7 +127,7 @@ async def serialize_response(
if is_coroutine:
value, errors_ = field.validate(response_content, {}, loc=("response",))
else:
value, errors_ = await run_in_threadpool(
value, errors_ = await run_in_threadpool( # type: ignore[misc]
field.validate, response_content, {}, loc=("response",)
)
if isinstance(errors_, ErrorWrapper):
Expand Down Expand Up @@ -478,11 +478,11 @@ def __init__(
),
) -> None:
super().__init__(
routes=routes, # type: ignore # in Starlette
routes=routes,
redirect_slashes=redirect_slashes,
default=default, # type: ignore # in Starlette
on_startup=on_startup, # type: ignore # in Starlette
on_shutdown=on_shutdown, # type: ignore # in Starlette
default=default,
on_startup=on_startup,
on_shutdown=on_shutdown,
)
if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'"
Expand Down Expand Up @@ -757,7 +757,7 @@ def include_router(
generate_unique_id_function=current_generate_unique_id,
)
elif isinstance(route, routing.Route):
methods = list(route.methods or []) # type: ignore # in Starlette
methods = list(route.methods or [])
self.add_route(
prefix + route.path,
route.endpoint,
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Expand Up @@ -26,7 +26,6 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand All @@ -35,11 +34,11 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP",
]
requires = [
"starlette ==0.17.1",
"starlette ==0.20.0",
Kludex marked this conversation as resolved.
Show resolved Hide resolved
"pydantic >=1.6.2,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0",
]
description-file = "README.md"
requires-python = ">=3.6.1"
requires-python = ">=3.7"

[tool.flit.metadata.urls]
Documentation = "https://fastapi.tiangolo.com/"
Expand Down Expand Up @@ -140,4 +139,5 @@ filterwarnings = [
"error",
# TODO: needed by asyncio in Python 3.9.7 https://bugs.python.org/issue45097, try to remove on 3.9.8
'ignore:The loop argument is deprecated since Python 3\.8, and scheduled for removal in Python 3\.10:DeprecationWarning:asyncio',
'ignore:starlette.middleware.wsgi is deprecated and will be removed in a future release\..*:DeprecationWarning:starlette'
]
6 changes: 3 additions & 3 deletions tests/test_extra_routes.py
Expand Up @@ -32,12 +32,12 @@ def delete_item(item_id: str, item: Item):

@app.head("/items/{item_id}")
def head_item(item_id: str):
return JSONResponse(headers={"x-fastapi-item-id": item_id})
return JSONResponse(None, headers={"x-fastapi-item-id": item_id})


@app.options("/items/{item_id}")
def options_item(item_id: str):
return JSONResponse(headers={"x-fastapi-item-id": item_id})
return JSONResponse(None, headers={"x-fastapi-item-id": item_id})


@app.patch("/items/{item_id}")
Expand All @@ -47,7 +47,7 @@ def patch_item(item_id: str, item: Item):

@app.trace("/items/{item_id}")
def trace_item(item_id: str):
return JSONResponse(media_type="message/http")
return JSONResponse(None, media_type="message/http")


client = TestClient(app)
Expand Down
Expand Up @@ -5,8 +5,6 @@
import pytest
from fastapi.testclient import TestClient

from ...utils import needs_py37

openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
Expand Down Expand Up @@ -340,14 +338,12 @@ def client():
test_db.unlink()


@needs_py37
def test_openapi_schema(client):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema


@needs_py37
def test_create_user(client):
test_user = {"email": "johndoe@example.com", "password": "secret"}
response = client.post("/users/", json=test_user)
Expand All @@ -359,7 +355,6 @@ def test_create_user(client):
assert response.status_code == 400, response.text


@needs_py37
def test_get_user(client):
response = client.get("/users/1")
assert response.status_code == 200, response.text
Expand All @@ -368,13 +363,11 @@ def test_get_user(client):
assert "id" in data


@needs_py37
def test_inexistent_user(client):
response = client.get("/users/999")
assert response.status_code == 404, response.text


@needs_py37
def test_get_users(client):
response = client.get("/users/")
assert response.status_code == 200, response.text
Expand All @@ -386,7 +379,6 @@ def test_get_users(client):
time.sleep = MagicMock()


@needs_py37
def test_get_slowusers(client):
response = client.get("/slowusers/")
assert response.status_code == 200, response.text
Expand All @@ -395,7 +387,6 @@ def test_get_slowusers(client):
assert "id" in data[0]


@needs_py37
def test_create_item(client):
item = {"title": "Foo", "description": "Something that fights"}
response = client.post("/users/1/items/", json=item)
Expand All @@ -419,7 +410,6 @@ def test_create_item(client):
assert item_to_check["description"] == item["description"]


@needs_py37
def test_read_items(client):
response = client.get("/items/")
assert response.status_code == 200, response.text
Expand Down
5 changes: 0 additions & 5 deletions tests/test_union_inherited_body.py
Expand Up @@ -4,8 +4,6 @@
from fastapi.testclient import TestClient
from pydantic import BaseModel

from .utils import needs_py37

# In Python 3.6:
tiangolo marked this conversation as resolved.
Show resolved Hide resolved
# u = Union[ExtendedItem, Item] == __main__.Item

Expand Down Expand Up @@ -118,21 +116,18 @@ def save_union_different_body(item: Union[ExtendedItem, Item]):
}


@needs_py37
def test_inherited_item_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == inherited_item_openapi_schema


@needs_py37
def test_post_extended_item():
response = client.post("/items/", json={"name": "Foo", "age": 5})
assert response.status_code == 200, response.text
assert response.json() == {"item": {"name": "Foo", "age": 5}}


@needs_py37
def test_post_item():
response = client.post("/items/", json={"name": "Foo"})
assert response.status_code == 200, response.text
Expand Down
1 change: 0 additions & 1 deletion tests/utils.py
Expand Up @@ -2,7 +2,6 @@

import pytest

needs_py37 = pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7+")
needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9+")
needs_py310 = pytest.mark.skipif(
sys.version_info < (3, 10), reason="requires python3.10+"
Expand Down