This commit is contained in:
2025-05-22 21:22:15 +02:00
parent 3d57f842f9
commit 97cb9c8703
156 changed files with 1205 additions and 6603 deletions

View File

@@ -1,7 +1,6 @@
from __future__ import annotations
import typing as t
import warnings
from io import BytesIO
from urllib.parse import parse_qsl
@@ -68,8 +67,6 @@ def default_stream_factory(
def parse_form_data(
environ: WSGIEnvironment,
stream_factory: TStreamFactory | None = None,
charset: str | None = None,
errors: str | None = None,
max_form_memory_size: int | None = None,
max_content_length: int | None = None,
cls: type[MultiDict] | None = None,
@@ -108,12 +105,11 @@ def parse_form_data(
is exceeded, a :exc:`~exceptions.RequestEntityTooLarge` exception is raised.
:return: A tuple in the form ``(stream, form, files)``.
.. versionchanged:: 2.3
Added the ``max_form_parts`` parameter.
.. versionchanged:: 3.0
The ``charset`` and ``errors`` parameters were removed.
.. versionchanged:: 2.3
The ``charset`` and ``errors`` parameters are deprecated and will be removed in
Werkzeug 3.0.
Added the ``max_form_parts`` parameter.
.. versionadded:: 0.5.1
Added the ``silent`` parameter.
@@ -124,8 +120,6 @@ def parse_form_data(
"""
return FormDataParser(
stream_factory=stream_factory,
charset=charset,
errors=errors,
max_form_memory_size=max_form_memory_size,
max_content_length=max_content_length,
max_form_parts=max_form_parts,
@@ -159,13 +153,11 @@ class FormDataParser:
:param max_form_parts: The maximum number of multipart parts to be parsed. If this
is exceeded, a :exc:`~exceptions.RequestEntityTooLarge` exception is raised.
.. versionchanged:: 2.3
The ``charset`` and ``errors`` parameters are deprecated and will be removed in
Werkzeug 3.0.
.. versionchanged:: 3.0
The ``charset`` and ``errors`` parameters were removed.
.. versionchanged:: 2.3
The ``parse_functions`` attribute and ``get_parse_func`` methods are deprecated
and will be removed in Werkzeug 3.0.
.. versionchanged:: 3.0
The ``parse_functions`` attribute and ``get_parse_func`` methods were removed.
.. versionchanged:: 2.2.3
Added the ``max_form_parts`` parameter.
@@ -176,8 +168,6 @@ class FormDataParser:
def __init__(
self,
stream_factory: TStreamFactory | None = None,
charset: str | None = None,
errors: str | None = None,
max_form_memory_size: int | None = None,
max_content_length: int | None = None,
cls: type[MultiDict] | None = None,
@@ -189,30 +179,6 @@ class FormDataParser:
stream_factory = default_stream_factory
self.stream_factory = stream_factory
if charset is not None:
warnings.warn(
"The 'charset' parameter is deprecated and will be"
" removed in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
else:
charset = "utf-8"
self.charset = charset
if errors is not None:
warnings.warn(
"The 'errors' parameter is deprecated and will be"
" removed in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
else:
errors = "replace"
self.errors = errors
self.max_form_memory_size = max_form_memory_size
self.max_content_length = max_content_length
self.max_form_parts = max_form_parts
@@ -223,44 +189,6 @@ class FormDataParser:
self.cls = cls
self.silent = silent
def get_parse_func(
self, mimetype: str, options: dict[str, str]
) -> None | (
t.Callable[
[FormDataParser, t.IO[bytes], str, int | None, dict[str, str]],
t_parse_result,
]
):
warnings.warn(
"The 'get_parse_func' method is deprecated and will be"
" removed in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
if mimetype == "multipart/form-data":
return type(self)._parse_multipart
elif mimetype == "application/x-www-form-urlencoded":
return type(self)._parse_urlencoded
elif mimetype == "application/x-url-encoded":
warnings.warn(
"The 'application/x-url-encoded' mimetype is invalid, and will not be"
" treated as 'application/x-www-form-urlencoded' in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
return type(self)._parse_urlencoded
elif mimetype in self.parse_functions:
warnings.warn(
"The 'parse_functions' attribute is deprecated and will be removed in"
" Werkzeug 3.0. Override 'parse' instead.",
DeprecationWarning,
stacklevel=2,
)
return self.parse_functions[mimetype]
return None
def parse_from_environ(self, environ: WSGIEnvironment) -> t_parse_result:
"""Parses the information from the environment as form data.
@@ -294,30 +222,14 @@ class FormDataParser:
the multipart boundary for instance)
:return: A tuple in the form ``(stream, form, files)``.
.. versionchanged:: 2.3
The ``application/x-url-encoded`` content type is deprecated and will not be
treated as ``application/x-www-form-urlencoded`` in Werkzeug 3.0.
.. versionchanged:: 3.0
The invalid ``application/x-url-encoded`` content type is not
treated as ``application/x-www-form-urlencoded``.
"""
if mimetype == "multipart/form-data":
parse_func = self._parse_multipart
elif mimetype == "application/x-www-form-urlencoded":
parse_func = self._parse_urlencoded
elif mimetype == "application/x-url-encoded":
warnings.warn(
"The 'application/x-url-encoded' mimetype is invalid, and will not be"
" treated as 'application/x-www-form-urlencoded' in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
parse_func = self._parse_urlencoded
elif mimetype in self.parse_functions:
warnings.warn(
"The 'parse_functions' attribute is deprecated and will be removed in"
" Werkzeug 3.0. Override 'parse' instead.",
DeprecationWarning,
stacklevel=2,
)
parse_func = self.parse_functions[mimetype].__get__(self, type(self))
else:
return stream, self.cls(), self.cls()
@@ -339,12 +251,8 @@ class FormDataParser:
content_length: int | None,
options: dict[str, str],
) -> t_parse_result:
charset = self.charset if self.charset != "utf-8" else None
errors = self.errors if self.errors != "replace" else None
parser = MultiPartParser(
stream_factory=self.stream_factory,
charset=charset,
errors=errors,
max_form_memory_size=self.max_form_memory_size,
max_form_parts=self.max_form_parts,
cls=self.cls,
@@ -375,7 +283,6 @@ class FormDataParser:
items = parse_qsl(
stream.read().decode(),
keep_blank_values=True,
encoding=self.charset,
errors="werkzeug.url_quote",
)
except ValueError as e:
@@ -383,49 +290,16 @@ class FormDataParser:
return stream, self.cls(items), self.cls()
parse_functions: dict[
str,
t.Callable[
[FormDataParser, t.IO[bytes], str, int | None, dict[str, str]],
t_parse_result,
],
] = {}
class MultiPartParser:
def __init__(
self,
stream_factory: TStreamFactory | None = None,
charset: str | None = None,
errors: str | None = None,
max_form_memory_size: int | None = None,
cls: type[MultiDict] | None = None,
buffer_size: int = 64 * 1024,
max_form_parts: int | None = None,
) -> None:
if charset is not None:
warnings.warn(
"The 'charset' parameter is deprecated and will be"
" removed in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
else:
charset = "utf-8"
self.charset = charset
if errors is not None:
warnings.warn(
"The 'errors' parameter is deprecated and will be"
" removed in Werkzeug 3.0.",
DeprecationWarning,
stacklevel=2,
)
else:
errors = "replace"
self.errors = errors
self.max_form_memory_size = max_form_memory_size
self.max_form_parts = max_form_parts
@@ -456,7 +330,7 @@ class MultiPartParser:
if ct_charset in {"ascii", "us-ascii", "utf-8", "iso-8859-1"}:
return ct_charset
return self.charset
return "utf-8"
def start_file_streaming(
self, event: File, total_content_length: int | None
@@ -509,7 +383,7 @@ class MultiPartParser:
if not event.more_data:
if isinstance(current_part, Field):
value = b"".join(container).decode(
self.get_part_charset(current_part.headers), self.errors
self.get_part_charset(current_part.headers), "replace"
)
fields.append((current_part.name, value))
else: