mirror of https://github.com/tiangolo/fastapi.git
♻️ Update logic to import and check `python-multipart` for compatibility with newer version (#12627)
This commit is contained in:
parent
aee7674ed2
commit
b31cbbf5f5
|
|
@ -89,16 +89,24 @@ multipart_incorrect_install_error = (
|
||||||
|
|
||||||
|
|
||||||
def ensure_multipart_is_installed() -> None:
|
def ensure_multipart_is_installed() -> None:
|
||||||
|
try:
|
||||||
|
from python_multipart import __version__
|
||||||
|
|
||||||
|
# Import an attribute that can be mocked/deleted in testing
|
||||||
|
assert __version__ > "0.0.12"
|
||||||
|
except (ImportError, AssertionError):
|
||||||
try:
|
try:
|
||||||
# __version__ is available in both multiparts, and can be mocked
|
# __version__ is available in both multiparts, and can be mocked
|
||||||
from multipart import __version__
|
from multipart import __version__ # type: ignore[no-redef,import-untyped]
|
||||||
|
|
||||||
assert __version__
|
assert __version__
|
||||||
try:
|
try:
|
||||||
# parse_options_header is only available in the right multipart
|
# parse_options_header is only available in the right multipart
|
||||||
from multipart.multipart import parse_options_header
|
from multipart.multipart import ( # type: ignore[import-untyped]
|
||||||
|
parse_options_header,
|
||||||
|
)
|
||||||
|
|
||||||
assert parse_options_header # type: ignore[truthy-function]
|
assert parse_options_header
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.error(multipart_incorrect_install_error)
|
logger.error(multipart_incorrect_install_error)
|
||||||
raise RuntimeError(multipart_incorrect_install_error) from None
|
raise RuntimeError(multipart_incorrect_install_error) from None
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import warnings
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi import FastAPI, File, Form, UploadFile
|
from fastapi import FastAPI, File, Form, UploadFile
|
||||||
from fastapi.dependencies.utils import (
|
from fastapi.dependencies.utils import (
|
||||||
|
|
@ -7,6 +9,9 @@ from fastapi.dependencies.utils import (
|
||||||
|
|
||||||
|
|
||||||
def test_incorrect_multipart_installed_form(monkeypatch):
|
def test_incorrect_multipart_installed_form(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -17,6 +22,9 @@ def test_incorrect_multipart_installed_form(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_incorrect_multipart_installed_file_upload(monkeypatch):
|
def test_incorrect_multipart_installed_file_upload(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -27,6 +35,9 @@ def test_incorrect_multipart_installed_file_upload(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_incorrect_multipart_installed_file_bytes(monkeypatch):
|
def test_incorrect_multipart_installed_file_bytes(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -37,6 +48,9 @@ def test_incorrect_multipart_installed_file_bytes(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_incorrect_multipart_installed_multi_form(monkeypatch):
|
def test_incorrect_multipart_installed_multi_form(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -47,6 +61,9 @@ def test_incorrect_multipart_installed_multi_form(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_incorrect_multipart_installed_form_file(monkeypatch):
|
def test_incorrect_multipart_installed_form_file(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -57,6 +74,9 @@ def test_incorrect_multipart_installed_form_file(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_no_multipart_installed(monkeypatch):
|
def test_no_multipart_installed(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.__version__", raising=False)
|
monkeypatch.delattr("multipart.__version__", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -67,6 +87,9 @@ def test_no_multipart_installed(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_no_multipart_installed_file(monkeypatch):
|
def test_no_multipart_installed_file(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.__version__", raising=False)
|
monkeypatch.delattr("multipart.__version__", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -77,6 +100,9 @@ def test_no_multipart_installed_file(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_no_multipart_installed_file_bytes(monkeypatch):
|
def test_no_multipart_installed_file_bytes(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.__version__", raising=False)
|
monkeypatch.delattr("multipart.__version__", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -87,6 +113,9 @@ def test_no_multipart_installed_file_bytes(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_no_multipart_installed_multi_form(monkeypatch):
|
def test_no_multipart_installed_multi_form(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.__version__", raising=False)
|
monkeypatch.delattr("multipart.__version__", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -97,6 +126,9 @@ def test_no_multipart_installed_multi_form(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_no_multipart_installed_form_file(monkeypatch):
|
def test_no_multipart_installed_form_file(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
monkeypatch.delattr("multipart.__version__", raising=False)
|
monkeypatch.delattr("multipart.__version__", raising=False)
|
||||||
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
with pytest.raises(RuntimeError, match=multipart_not_installed_error):
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
@ -104,3 +136,14 @@ def test_no_multipart_installed_form_file(monkeypatch):
|
||||||
@app.post("/")
|
@app.post("/")
|
||||||
async def root(username: str = Form(), f: UploadFile = File()):
|
async def root(username: str = Form(), f: UploadFile = File()):
|
||||||
return username # pragma: nocover
|
return username # pragma: nocover
|
||||||
|
|
||||||
|
|
||||||
|
def test_old_multipart_installed(monkeypatch):
|
||||||
|
monkeypatch.setattr("python_multipart.__version__", "0.0.12")
|
||||||
|
with warnings.catch_warnings(record=True):
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
@app.post("/")
|
||||||
|
async def root(username: str = Form()):
|
||||||
|
return username # pragma: nocover
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue