Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Werkzeug for openSUSE:Factory
checked in at 2024-11-12 19:19:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Werkzeug (Old)
and /work/SRC/openSUSE:Factory/.python-Werkzeug.new.2017 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Werkzeug"
Tue Nov 12 19:19:57 2024 rev:50 rq:1223597 version:3.1.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Werkzeug/python-Werkzeug.changes
2024-11-06 16:50:19.040014677 +0100
+++
/work/SRC/openSUSE:Factory/.python-Werkzeug.new.2017/python-Werkzeug.changes
2024-11-12 19:20:10.132319105 +0100
@@ -1,0 +2,17 @@
+Tue Nov 12 07:59:40 UTC 2024 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to 3.1.3
+ * Initial data passed to ``MultiDict`` and similar interfaces only accepts
+ ``list``, ``tuple``, or ``set`` when passing multiple values. It had been
+ changed to accept any ``Collection``, but this matched types that should be
+ treated as single values, such as ``bytes``. :issue:`2994`
+ * When the ``Host`` header is not set and ``Request.host`` falls back to the
+ WSGI ``SERVER_NAME`` value, if that value is an IPv6 address it is wrapped
+ in ``[]`` to match the ``Host`` header. :issue:`2993`
+- from version 3.1.2
+ * Improve type annotation for ``TypeConversionDict.get`` to allow the
``type``
+ parameter to be a callable. :issue:`2988`
+ * ``Headers`` does not inherit from ``MutableMapping``, as it is does not
+ exactly match that interface. :issue:`2989`
+
+-------------------------------------------------------------------
Old:
----
werkzeug-3.1.1.tar.gz
New:
----
werkzeug-3.1.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Werkzeug.spec ++++++
--- /var/tmp/diff_new_pack.S2EZ3f/_old 2024-11-12 19:20:11.036356982 +0100
+++ /var/tmp/diff_new_pack.S2EZ3f/_new 2024-11-12 19:20:11.040357149 +0100
@@ -27,7 +27,7 @@
%{?sle15_python_module_pythons}
Name: python-Werkzeug%{psuffix}
-Version: 3.1.1
+Version: 3.1.3
Release: 0
Summary: The Swiss Army knife of Python web development
License: BSD-3-Clause
++++++ werkzeug-3.1.1.tar.gz -> werkzeug-3.1.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/CHANGES.rst
new/werkzeug-3.1.3/CHANGES.rst
--- old/werkzeug-3.1.1/CHANGES.rst 2024-11-01 17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/CHANGES.rst 2024-11-08 16:46:09.000000000 +0100
@@ -1,5 +1,30 @@
.. currentmodule:: werkzeug
+Version 3.1.3
+-------------
+
+Released 2024-11-08
+
+- Initial data passed to ``MultiDict`` and similar interfaces only accepts
+ ``list``, ``tuple``, or ``set`` when passing multiple values. It had been
+ changed to accept any ``Collection``, but this matched types that should be
+ treated as single values, such as ``bytes``. :issue:`2994`
+- When the ``Host`` header is not set and ``Request.host`` falls back to the
+ WSGI ``SERVER_NAME`` value, if that value is an IPv6 address it is wrapped
+ in ``[]`` to match the ``Host`` header. :issue:`2993`
+
+
+Version 3.1.2
+-------------
+
+Released 2024-11-04
+
+- Improve type annotation for ``TypeConversionDict.get`` to allow the
``type``
+ parameter to be a callable. :issue:`2988`
+- ``Headers`` does not inherit from ``MutableMapping``, as it is does not
+ exactly match that interface. :issue:`2989`
+
+
Version 3.1.1
-------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/PKG-INFO new/werkzeug-3.1.3/PKG-INFO
--- old/werkzeug-3.1.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/werkzeug-3.1.3/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.3
Name: Werkzeug
-Version: 3.1.1
+Version: 3.1.3
Summary: The comprehensive WSGI web application library.
Maintainer-email: Pallets <[email protected]>
Requires-Python: >=3.9
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/pyproject.toml
new/werkzeug-3.1.3/pyproject.toml
--- old/werkzeug-3.1.1/pyproject.toml 2024-11-01 17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/pyproject.toml 2024-11-08 16:46:09.000000000 +0100
@@ -1,6 +1,6 @@
[project]
name = "Werkzeug"
-version = "3.1.1"
+version = "3.1.3"
description = "The comprehensive WSGI web application library."
readme = "README.md"
license = {file = "LICENSE.txt"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/werkzeug-3.1.1/src/werkzeug/datastructures/headers.py
new/werkzeug-3.1.3/src/werkzeug/datastructures/headers.py
--- old/werkzeug-3.1.1/src/werkzeug/datastructures/headers.py 2024-11-01
17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/src/werkzeug/datastructures/headers.py 2024-11-08
16:46:09.000000000 +0100
@@ -17,7 +17,7 @@
T = t.TypeVar("T")
-class Headers(cabc.MutableMapping[str, str]):
+class Headers:
"""An object that stores some headers. It has a dict-like interface,
but is ordered, can store the same key multiple times, and iterating
yields ``(key, value)`` pairs instead of only keys.
@@ -62,7 +62,7 @@
defaults: (
Headers
| MultiDict[str, t.Any]
- | cabc.Mapping[str, t.Any | cabc.Collection[t.Any]]
+ | cabc.Mapping[str, t.Any | list[t.Any] | tuple[t.Any, ...] |
set[t.Any]]
| cabc.Iterable[tuple[str, t.Any]]
| None
) = None,
@@ -107,18 +107,21 @@
__hash__ = None # type: ignore[assignment]
- @t.overload # type: ignore[override]
+ @t.overload
def get(self, key: str) -> str | None: ...
@t.overload
def get(self, key: str, default: str) -> str: ...
@t.overload
def get(self, key: str, default: T) -> str | T: ...
@t.overload
- def get(self, key: str, type: type[T]) -> T | None: ...
+ def get(self, key: str, type: cabc.Callable[[str], T]) -> T | None: ...
@t.overload
- def get(self, key: str, default: T, type: type[T]) -> T: ...
+ def get(self, key: str, default: T, type: cabc.Callable[[str], T]) -> T:
...
def get( # type: ignore[misc]
- self, key: str, default: str | T | None = None, type: type[T] | None =
None
+ self,
+ key: str,
+ default: str | T | None = None,
+ type: cabc.Callable[[str], T] | None = None,
) -> str | T | None:
"""Return the default value if the requested data doesn't exist.
If `type` is provided and is a callable it should convert the value,
@@ -153,15 +156,17 @@
return rv
try:
- return type(rv) # type: ignore[call-arg]
+ return type(rv)
except ValueError:
return default
@t.overload
def getlist(self, key: str) -> list[str]: ...
@t.overload
- def getlist(self, key: str, type: type[T]) -> list[T]: ...
- def getlist(self, key: str, type: type[T] | None = None) -> list[str] |
list[T]:
+ def getlist(self, key: str, type: cabc.Callable[[str], T]) -> list[T]: ...
+ def getlist(
+ self, key: str, type: cabc.Callable[[str], T] | None = None
+ ) -> list[str] | list[T]:
"""Return the list of items for a given key. If that key is not in the
:class:`Headers`, the return value will be an empty list. Just like
:meth:`get`, :meth:`getlist` accepts a `type` parameter. All items
will
@@ -187,7 +192,7 @@
for k, v in self:
if k.lower() == ikey:
try:
- result.append(type(v)) # type: ignore[call-arg]
+ result.append(type(v))
except ValueError:
continue
@@ -203,17 +208,17 @@
"""
return self.getlist(name)
- def items(self, lower: bool = False) -> t.Iterable[tuple[str, str]]: #
type: ignore[override]
+ def items(self, lower: bool = False) -> t.Iterable[tuple[str, str]]:
for key, value in self:
if lower:
key = key.lower()
yield key, value
- def keys(self, lower: bool = False) -> t.Iterable[str]: # type:
ignore[override]
+ def keys(self, lower: bool = False) -> t.Iterable[str]:
for key, _ in self.items(lower):
yield key
- def values(self) -> t.Iterable[str]: # type: ignore[override]
+ def values(self) -> t.Iterable[str]:
for _, value in self.items():
yield value
@@ -222,7 +227,7 @@
arg: (
Headers
| MultiDict[str, t.Any]
- | cabc.Mapping[str, t.Any | cabc.Collection[t.Any]]
+ | cabc.Mapping[str, t.Any | list[t.Any] | tuple[t.Any, ...] |
set[t.Any]]
| cabc.Iterable[tuple[str, t.Any]]
| None
) = None,
@@ -317,7 +322,7 @@
"""Removes a key or index and returns a (key, value) item."""
return self._list.pop()
- def __contains__(self, key: str) -> bool: # type: ignore[override]
+ def __contains__(self, key: str) -> bool:
"""Check if a key is present."""
try:
self._get_key(key)
@@ -326,7 +331,7 @@
return True
- def __iter__(self) -> t.Iterator[tuple[str, str]]: # type:
ignore[override]
+ def __iter__(self) -> t.Iterator[tuple[str, str]]:
"""Yield ``(key, value)`` tuples."""
return iter(self._list)
@@ -481,17 +486,19 @@
else:
self._list[key] = [(k, _str_header_value(v)) for k, v in value] #
type: ignore[misc]
- def update( # type: ignore[override]
+ def update(
self,
arg: (
Headers
| MultiDict[str, t.Any]
- | cabc.Mapping[str, t.Any | cabc.Collection[t.Any]]
+ | cabc.Mapping[
+ str, t.Any | list[t.Any] | tuple[t.Any, ...] | cabc.Set[t.Any]
+ ]
| cabc.Iterable[tuple[str, t.Any]]
| None
) = None,
/,
- **kwargs: t.Any | cabc.Collection[t.Any],
+ **kwargs: t.Any | list[t.Any] | tuple[t.Any, ...] | cabc.Set[t.Any],
) -> None:
"""Replace headers in this object with items from another
headers object and keyword arguments.
@@ -511,9 +518,7 @@
self.setlist(key, arg.getlist(key))
elif isinstance(arg, cabc.Mapping):
for key, value in arg.items():
- if isinstance(value, cabc.Collection) and not isinstance(
- value, str
- ):
+ if isinstance(value, (list, tuple, set)):
self.setlist(key, value)
else:
self.set(key, value)
@@ -522,13 +527,16 @@
self.set(key, value)
for key, value in kwargs.items():
- if isinstance(value, cabc.Collection) and not isinstance(value,
str):
+ if isinstance(value, (list, tuple, set)):
self.setlist(key, value)
else:
self.set(key, value)
def __or__(
- self, other: cabc.Mapping[str, t.Any | cabc.Collection[t.Any]]
+ self,
+ other: cabc.Mapping[
+ str, t.Any | list[t.Any] | tuple[t.Any, ...] | cabc.Set[t.Any]
+ ],
) -> te.Self:
if not isinstance(other, cabc.Mapping):
return NotImplemented
@@ -540,13 +548,11 @@
def __ior__(
self,
other: (
- cabc.Mapping[str, t.Any | cabc.Collection[t.Any]]
+ cabc.Mapping[str, t.Any | list[t.Any] | tuple[t.Any, ...] |
cabc.Set[t.Any]]
| cabc.Iterable[tuple[str, t.Any]]
),
) -> te.Self:
- if not isinstance(other, (cabc.Mapping, cabc.Iterable)) or isinstance(
- other, str
- ):
+ if not isinstance(other, (cabc.Mapping, cabc.Iterable)):
return NotImplemented
self.update(other)
@@ -557,7 +563,7 @@
:return: list
"""
- return list(self) # type: ignore[arg-type]
+ return list(self)
def copy(self) -> te.Self:
return self.__class__(self._list)
@@ -635,7 +641,7 @@
def __len__(self) -> int:
return sum(1 for _ in self)
- def __iter__(self) -> cabc.Iterator[tuple[str, str]]: # type:
ignore[override]
+ def __iter__(self) -> cabc.Iterator[tuple[str, str]]:
for key, value in self.environ.items():
if key.startswith("HTTP_") and key not in {
"HTTP_CONTENT_TYPE",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/werkzeug-3.1.1/src/werkzeug/datastructures/structures.py
new/werkzeug-3.1.3/src/werkzeug/datastructures/structures.py
--- old/werkzeug-3.1.1/src/werkzeug/datastructures/structures.py
2024-11-01 17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/src/werkzeug/datastructures/structures.py
2024-11-08 16:46:09.000000000 +0100
@@ -22,7 +22,7 @@
def iter_multi_items(
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
),
) -> cabc.Iterator[tuple[K, V]]:
@@ -33,11 +33,11 @@
yield from mapping.items(multi=True)
elif isinstance(mapping, cabc.Mapping):
for key, value in mapping.items():
- if isinstance(value, cabc.Collection) and not isinstance(value,
str):
+ if isinstance(value, (list, tuple, set)):
for v in value:
yield key, v
else:
- yield key, value # type: ignore[misc]
+ yield key, value
else:
yield from mapping
@@ -69,11 +69,14 @@
@t.overload
def get(self, key: K, default: T) -> V | T: ...
@t.overload
- def get(self, key: str, type: type[T]) -> T | None: ...
+ def get(self, key: str, type: cabc.Callable[[V], T]) -> T | None: ...
@t.overload
- def get(self, key: str, default: T, type: type[T]) -> T: ...
+ def get(self, key: str, default: T, type: cabc.Callable[[V], T]) -> T: ...
def get( # type: ignore[misc]
- self, key: K, default: V | T | None = None, type: type[T] | None = None
+ self,
+ key: K,
+ default: V | T | None = None,
+ type: cabc.Callable[[V], T] | None = None,
) -> V | T | None:
"""Return the default value if the requested data doesn't exist.
If `type` is provided and is a callable it should convert the value,
@@ -108,7 +111,7 @@
return rv
try:
- return type(rv) # type: ignore[call-arg]
+ return type(rv)
except (ValueError, TypeError):
return default
@@ -179,7 +182,7 @@
self,
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
| None
) = None,
@@ -191,7 +194,7 @@
elif isinstance(mapping, cabc.Mapping):
tmp = {}
for key, value in mapping.items():
- if isinstance(value, cabc.Collection) and not
isinstance(value, str):
+ if isinstance(value, (list, tuple, set)):
value = list(value)
if not value:
@@ -255,8 +258,10 @@
@t.overload
def getlist(self, key: K) -> list[V]: ...
@t.overload
- def getlist(self, key: K, type: type[T]) -> list[T]: ...
- def getlist(self, key: K, type: type[T] | None = None) -> list[V] |
list[T]:
+ def getlist(self, key: K, type: cabc.Callable[[V], T]) -> list[T]: ...
+ def getlist(
+ self, key: K, type: cabc.Callable[[V], T] | None = None
+ ) -> list[V] | list[T]:
"""Return the list of items for a given key. If that key is not in the
`MultiDict`, the return value will be an empty list. Just like `get`,
`getlist` accepts a `type` parameter. All items will be converted
@@ -279,7 +284,7 @@
result = []
for item in rv:
try:
- result.append(type(item)) # type: ignore[call-arg]
+ result.append(type(item))
except (ValueError, TypeError):
pass
return result
@@ -414,7 +419,7 @@
self,
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
),
) -> None:
@@ -439,7 +444,7 @@
self.add(key, value)
def __or__( # type: ignore[override]
- self, other: cabc.Mapping[K, V | cabc.Collection[V]]
+ self, other: cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
) -> MultiDict[K, V]:
if not isinstance(other, cabc.Mapping):
return NotImplemented
@@ -450,11 +455,12 @@
def __ior__( # type: ignore[override]
self,
- other: cabc.Mapping[K, V | cabc.Collection[V]] |
cabc.Iterable[tuple[K, V]],
+ other: (
+ cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
+ | cabc.Iterable[tuple[K, V]]
+ ),
) -> te.Self:
- if not isinstance(other, (cabc.Mapping, cabc.Iterable)) or isinstance(
- other, str
- ):
+ if not isinstance(other, (cabc.Mapping, cabc.Iterable)):
return NotImplemented
self.update(other)
@@ -595,7 +601,7 @@
self,
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
| None
) = None,
@@ -707,8 +713,10 @@
@t.overload
def getlist(self, key: K) -> list[V]: ...
@t.overload
- def getlist(self, key: K, type: type[T]) -> list[T]: ...
- def getlist(self, key: K, type: type[T] | None = None) -> list[V] |
list[T]:
+ def getlist(self, key: K, type: cabc.Callable[[V], T]) -> list[T]: ...
+ def getlist(
+ self, key: K, type: cabc.Callable[[V], T] | None = None
+ ) -> list[V] | list[T]:
rv: list[_omd_bucket[K, V]]
try:
@@ -720,7 +728,7 @@
result = []
for item in rv:
try:
- result.append(type(item.value)) # type: ignore[call-arg]
+ result.append(type(item.value))
except (ValueError, TypeError):
pass
return result
@@ -737,7 +745,7 @@
self,
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
),
) -> None:
@@ -852,17 +860,20 @@
@t.overload
def get(self, key: K, default: T) -> V | T: ...
@t.overload
- def get(self, key: str, type: type[T]) -> T | None: ...
+ def get(self, key: str, type: cabc.Callable[[V], T]) -> T | None: ...
@t.overload
- def get(self, key: str, default: T, type: type[T]) -> T: ...
+ def get(self, key: str, default: T, type: cabc.Callable[[V], T]) -> T: ...
def get( # type: ignore[misc]
- self, key: K, default: V | T | None = None, type: type[T] | None = None
+ self,
+ key: K,
+ default: V | T | None = None,
+ type: cabc.Callable[[V], T] | None = None,
) -> V | T | None:
for d in self.dicts:
if key in d:
if type is not None:
try:
- return type(d[key]) # type: ignore[call-arg]
+ return type(d[key])
except (ValueError, TypeError):
continue
return d[key]
@@ -871,8 +882,10 @@
@t.overload
def getlist(self, key: K) -> list[V]: ...
@t.overload
- def getlist(self, key: K, type: type[T]) -> list[T]: ...
- def getlist(self, key: K, type: type[T] | None = None) -> list[V] |
list[T]:
+ def getlist(self, key: K, type: cabc.Callable[[V], T]) -> list[T]: ...
+ def getlist(
+ self, key: K, type: cabc.Callable[[V], T] | None = None
+ ) -> list[V] | list[T]:
rv = []
for d in self.dicts:
rv.extend(d.getlist(key, type)) # type: ignore[arg-type]
@@ -997,7 +1010,7 @@
self,
mapping: (
MultiDict[K, V]
- | cabc.Mapping[K, V | cabc.Collection[V]]
+ | cabc.Mapping[K, V | list[V] | tuple[V, ...] | set[V]]
| cabc.Iterable[tuple[K, V]]
| None
) = None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/src/werkzeug/sansio/utils.py
new/werkzeug-3.1.3/src/werkzeug/sansio/utils.py
--- old/werkzeug-3.1.1/src/werkzeug/sansio/utils.py 2024-11-01
17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/src/werkzeug/sansio/utils.py 2024-11-08
16:46:09.000000000 +0100
@@ -71,6 +71,9 @@
:return: Host, with port if necessary.
:raise ~werkzeug.exceptions.SecurityError: If the host is not
trusted.
+
+ .. versionchanged:: 3.1.3
+ If ``SERVER_NAME`` is IPv6, it is wrapped in ``[]``.
"""
host = ""
@@ -79,6 +82,11 @@
elif server is not None:
host = server[0]
+ # If SERVER_NAME is IPv6, wrap it in [] to match Host header.
+ # Check for : because domain or IPv4 can't have that.
+ if ":" in host and host[0] != "[":
+ host = f"[{host}]"
+
if server[1] is not None:
host = f"{host}:{server[1]}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/src/werkzeug/utils.py
new/werkzeug-3.1.3/src/werkzeug/utils.py
--- old/werkzeug-3.1.1/src/werkzeug/utils.py 2024-11-01 17:18:41.000000000
+0100
+++ new/werkzeug-3.1.3/src/werkzeug/utils.py 2024-11-08 16:46:09.000000000
+0100
@@ -150,7 +150,7 @@
class header_property(_DictAccessorProperty[_TAccessorValue]):
"""Like `environ_property` but for headers."""
- def lookup(self, obj: Request | Response) -> Headers:
+ def lookup(self, obj: Request | Response) -> Headers: # type:
ignore[override]
return obj.headers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/tests/sansio/test_utils.py
new/werkzeug-3.1.3/tests/sansio/test_utils.py
--- old/werkzeug-3.1.1/tests/sansio/test_utils.py 2024-11-01
17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/tests/sansio/test_utils.py 2024-11-08
16:46:09.000000000 +0100
@@ -14,12 +14,16 @@
("https", "spam", None, "spam"),
("https", "spam:443", None, "spam"),
("http", "spam:8080", None, "spam:8080"),
+ ("http", "127.0.0.1:8080", None, "127.0.0.1:8080"),
+ ("http", "[::1]:8080", None, "[::1]:8080"),
("ws", "spam", None, "spam"),
("ws", "spam:80", None, "spam"),
("wss", "spam", None, "spam"),
("wss", "spam:443", None, "spam"),
("http", None, ("spam", 80), "spam"),
("http", None, ("spam", 8080), "spam:8080"),
+ ("http", None, ("127.0.0.1", 8080), "127.0.0.1:8080"),
+ ("http", None, ("::1", 8080), "[::1]:8080"),
("http", None, ("unix/socket", None), "unix/socket"),
("http", "spam", ("eggs", 80), "spam"),
],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/werkzeug-3.1.1/tests/test_datastructures.py
new/werkzeug-3.1.3/tests/test_datastructures.py
--- old/werkzeug-3.1.1/tests/test_datastructures.py 2024-11-01
17:18:41.000000000 +0100
+++ new/werkzeug-3.1.3/tests/test_datastructures.py 2024-11-08
16:46:09.000000000 +0100
@@ -1,6 +1,9 @@
+from __future__ import annotations
+
import io
import pickle
import tempfile
+import typing as t
from contextlib import contextmanager
from copy import copy
from copy import deepcopy
@@ -43,7 +46,7 @@
class _MutableMultiDictTests:
- storage_class: type["ds.MultiDict"]
+ storage_class: type[ds.MultiDict]
def test_pickle(self):
cls = self.storage_class
@@ -1280,3 +1283,15 @@
def test_range_validates_ranges(ranges):
with pytest.raises(ValueError):
ds.Range("bytes", ranges)
+
+
[email protected](
+ ("value", "expect"),
+ [
+ ({"a": "ab"}, [("a", "ab")]),
+ ({"a": ["a", "b"]}, [("a", "a"), ("a", "b")]),
+ ({"a": b"ab"}, [("a", b"ab")]),
+ ],
+)
+def test_iter_multi_data(value: t.Any, expect: list[tuple[t.Any, t.Any]]) ->
None:
+ assert list(ds.iter_multi_items(value)) == expect