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 2022-05-12 22:58:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Werkzeug (Old) and /work/SRC/openSUSE:Factory/.python-Werkzeug.new.1538 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Werkzeug" Thu May 12 22:58:14 2022 rev:37 rq:976285 version:2.1.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Werkzeug/python-Werkzeug.changes 2022-05-08 21:52:33.439478592 +0200 +++ /work/SRC/openSUSE:Factory/.python-Werkzeug.new.1538/python-Werkzeug.changes 2022-05-12 22:58:33.792652028 +0200 @@ -1,0 +2,15 @@ +Wed May 11 10:40:41 UTC 2022 - Dirk M??ller <dmuel...@suse.com> + +- update to 2.1.2: + * The development server does not set ``Transfer-Encoding: chunked`` + for 1xx, 204, 304, and HEAD responses. :issue:`2375` + * Response HTML for exceptions and redirects starts with + ``<!doctype html>`` and ``<html lang=en>``. :issue:`2390` + * Fix ability to set some ``cache_control`` attributes to ``False``. + :issue:`2379` + * Disable ``keep-alive`` connections in the development server, which + are not supported sufficiently by Python's ``http.server``. + :issue:`2397` +- drop 2402-dev_server.patch (upstream) + +------------------------------------------------------------------- Old: ---- 2402-dev_server.patch Werkzeug-2.1.1.tar.gz New: ---- Werkzeug-2.1.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Werkzeug.spec ++++++ --- /var/tmp/diff_new_pack.KWm65u/_old 2022-05-12 22:58:34.216652597 +0200 +++ /var/tmp/diff_new_pack.KWm65u/_new 2022-05-12 22:58:34.224652608 +0200 @@ -20,17 +20,13 @@ %define skip_python2 1 %define skip_python36 1 Name: python-Werkzeug -Version: 2.1.1 +Version: 2.1.2 Release: 0 Summary: The Swiss Army knife of Python web development License: BSD-3-Clause Group: Development/Languages/Python URL: https://werkzeug.palletsprojects.com Source: https://files.pythonhosted.org/packages/source/W/Werkzeug/Werkzeug-%{version}.tar.gz -# PATCH-FIX-UPSTREAM 2402-dev_server.patch gh#pallets/werkzeug#2393 mc...@suse.com -# upstream solution to mark tests which require development server -# from https://github.com/pallets/werkzeug/pull/2402 -Patch0: 2402-dev_server.patch # PATCH-FIX-UPSTREAM moved_root.patch bsc#[0-9]+ mc...@suse.com # this patch makes things totally awesome Patch1: moved_root.patch ++++++ Werkzeug-2.1.1.tar.gz -> Werkzeug-2.1.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/CHANGES.rst new/Werkzeug-2.1.2/CHANGES.rst --- old/Werkzeug-2.1.1/CHANGES.rst 2022-04-01 18:00:05.000000000 +0200 +++ new/Werkzeug-2.1.2/CHANGES.rst 2022-04-28 19:38:40.000000000 +0200 @@ -1,5 +1,21 @@ .. currentmodule:: werkzeug +Version 2.1.2 +------------- + +Released 2022-04-28 + +- The development server does not set ``Transfer-Encoding: chunked`` + for 1xx, 204, 304, and HEAD responses. :issue:`2375` +- Response HTML for exceptions and redirects starts with + ``<!doctype html>`` and ``<html lang=en>``. :issue:`2390` +- Fix ability to set some ``cache_control`` attributes to ``False``. + :issue:`2379` +- Disable ``keep-alive`` connections in the development server, which + are not supported sufficiently by Python's ``http.server``. + :issue:`2397` + + Version 2.1.1 ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/PKG-INFO new/Werkzeug-2.1.2/PKG-INFO --- old/Werkzeug-2.1.1/PKG-INFO 2022-04-01 18:00:45.271357000 +0200 +++ new/Werkzeug-2.1.2/PKG-INFO 2022-04-28 19:39:13.677677000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Werkzeug -Version: 2.1.1 +Version: 2.1.2 Summary: The comprehensive WSGI web application library. Home-page: https://palletsprojects.com/p/werkzeug/ Author: Armin Ronacher diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/docs/routing.rst new/Werkzeug-2.1.2/docs/routing.rst --- old/Werkzeug-2.1.1/docs/routing.rst 2021-02-12 18:26:46.000000000 +0100 +++ new/Werkzeug-2.1.2/docs/routing.rst 2022-04-28 17:53:45.000000000 +0200 @@ -42,7 +42,7 @@ except HTTPException, e: return e(environ, start_response) start_response('200 OK', [('Content-Type', 'text/plain')]) - return [f'Rule points to {endpoint!r} with arguments {args!r}'] + return [f'Rule points to {endpoint!r} with arguments {args!r}'.encode()] So what does that do? First of all we create a new :class:`Map` which stores a bunch of URL rules. Then we pass it a list of :class:`Rule` objects. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/docs/test.rst new/Werkzeug-2.1.2/docs/test.rst --- old/Werkzeug-2.1.1/docs/test.rst 2021-02-12 19:11:39.000000000 +0100 +++ new/Werkzeug-2.1.2/docs/test.rst 2022-04-25 20:08:23.000000000 +0200 @@ -21,7 +21,7 @@ >>> resp.headers Headers([('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', '6658')]) >>> response.get_data(as_text=True) -'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"...' +'<!doctype html>...' The client's request methods return instances of :class:`TestResponse`. This provides extra attributes and methods on top of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/coolmagic/templates/layout.html new/Werkzeug-2.1.2/examples/coolmagic/templates/layout.html --- old/Werkzeug-2.1.1/examples/coolmagic/templates/layout.html 2019-09-07 15:32:19.000000000 +0200 +++ new/Werkzeug-2.1.2/examples/coolmagic/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> +<!doctype html> <html> <head> <title>{{ page_title }} — Cool Magic!</title> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/couchy/templates/layout.html new/Werkzeug-2.1.2/examples/couchy/templates/layout.html --- old/Werkzeug-2.1.1/examples/couchy/templates/layout.html 2019-09-07 15:32:19.000000000 +0200 +++ new/Werkzeug-2.1.2/examples/couchy/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> +<!doctype html> <html> <head> <title>Shorty</title> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/cupoftee/templates/layout.html new/Werkzeug-2.1.2/examples/cupoftee/templates/layout.html --- old/Werkzeug-2.1.1/examples/cupoftee/templates/layout.html 2021-01-15 22:13:50.000000000 +0100 +++ new/Werkzeug-2.1.2/examples/cupoftee/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> +<!doctype html> <html> <head> <title>Teeworlds Server Browser</title> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/i18nurls/templates/layout.html new/Werkzeug-2.1.2/examples/i18nurls/templates/layout.html --- old/Werkzeug-2.1.1/examples/i18nurls/templates/layout.html 2021-01-15 22:13:50.000000000 +0100 +++ new/Werkzeug-2.1.2/examples/i18nurls/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> +<!doctype html> <html> <head> <title>{{ title }} | Example Application</title> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/plnt/templates/layout.html new/Werkzeug-2.1.2/examples/plnt/templates/layout.html --- old/Werkzeug-2.1.1/examples/plnt/templates/layout.html 2019-09-07 15:32:19.000000000 +0200 +++ new/Werkzeug-2.1.2/examples/plnt/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> +<!doctype html> <title>Plnt Planet</title> <link rel="stylesheet" type="text/css" href="{{ url_for('shared', file='style.css')??}}"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/examples/shorty/templates/layout.html new/Werkzeug-2.1.2/examples/shorty/templates/layout.html --- old/Werkzeug-2.1.1/examples/shorty/templates/layout.html 2019-09-07 15:32:19.000000000 +0200 +++ new/Werkzeug-2.1.2/examples/shorty/templates/layout.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> +<!doctype html> <html> <head> <title>Shorty</title> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/requirements/dev.txt new/Werkzeug-2.1.2/requirements/dev.txt --- old/Werkzeug-2.1.1/requirements/dev.txt 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/requirements/dev.txt 2022-04-28 17:53:45.000000000 +0200 @@ -10,31 +10,31 @@ -r typing.txt cfgv==3.3.1 # via pre-commit -click==8.0.3 +click==8.1.2 # via # pip-compile-multi # pip-tools distlib==0.3.4 # via virtualenv -filelock==3.4.2 +filelock==3.6.0 # via # tox # virtualenv greenlet==1.1.2 ; python_version < "3.11" # via -r requirements/tests.in -identify==2.4.8 +identify==2.5.0 # via pre-commit nodeenv==1.6.0 # via pre-commit pep517==0.12.0 # via pip-tools -pip-compile-multi==2.4.3 +pip-compile-multi==2.4.5 # via -r requirements/dev.in -pip-tools==6.5.0 +pip-tools==6.6.0 # via pip-compile-multi -platformdirs==2.4.1 +platformdirs==2.5.2 # via virtualenv -pre-commit==2.17.0 +pre-commit==2.18.1 # via -r requirements/dev.in pyyaml==6.0 # via pre-commit @@ -48,9 +48,9 @@ # tox toposort==1.7 # via pip-compile-multi -tox==3.24.5 +tox==3.25.0 # via -r requirements/dev.in -virtualenv==20.13.1 +virtualenv==20.14.1 # via # pre-commit # tox diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/requirements/docs.txt new/Werkzeug-2.1.2/requirements/docs.txt --- old/Werkzeug-2.1.1/requirements/docs.txt 2022-02-07 20:13:39.000000000 +0100 +++ new/Werkzeug-2.1.2/requirements/docs.txt 2022-04-28 16:14:01.000000000 +0200 @@ -7,11 +7,11 @@ # alabaster==0.7.12 # via sphinx -babel==2.9.1 +babel==2.10.1 # via sphinx certifi==2021.10.8 # via requests -charset-normalizer==2.0.11 +charset-normalizer==2.0.12 # via requests docutils==0.17.1 # via sphinx @@ -19,9 +19,9 @@ # via requests imagesize==1.3.0 # via sphinx -jinja2==3.0.3 +jinja2==3.1.1 # via sphinx -markupsafe==2.0.1 +markupsafe==2.1.1 # via jinja2 packaging==21.3 # via @@ -29,17 +29,17 @@ # sphinx pallets-sphinx-themes==2.0.2 # via -r requirements/docs.in -pygments==2.11.2 +pygments==2.12.0 # via sphinx -pyparsing==3.0.7 +pyparsing==3.0.8 # via packaging -pytz==2021.3 +pytz==2022.1 # via babel requests==2.27.1 # via sphinx snowballstemmer==2.2.0 # via sphinx -sphinx==4.4.0 +sphinx==4.5.0 # via # -r requirements/docs.in # pallets-sphinx-themes @@ -61,5 +61,5 @@ # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -urllib3==1.26.8 +urllib3==1.26.9 # via requests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/requirements/tests.txt new/Werkzeug-2.1.2/requirements/tests.txt --- old/Werkzeug-2.1.1/requirements/tests.txt 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/requirements/tests.txt 2022-04-28 17:53:45.000000000 +0200 @@ -9,7 +9,7 @@ # via pytest cffi==1.15.0 # via cryptography -cryptography==36.0.1 +cryptography==37.0.1 # via -r requirements/tests.in ephemeral-port-reserve==1.1.4 # via -r requirements/tests.in @@ -27,9 +27,9 @@ # via pytest pycparser==2.21 # via cffi -pyparsing==3.0.7 +pyparsing==3.0.8 # via packaging -pytest==7.0.0 +pytest==7.1.2 # via # -r requirements/tests.in # pytest-timeout @@ -38,7 +38,7 @@ # via -r requirements/tests.in pytest-xprocess==0.18.1 # via -r requirements/tests.in -tomli==2.0.0 +tomli==2.0.1 # via pytest -watchdog==2.1.6 +watchdog==2.1.7 # via -r requirements/tests.in diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/requirements/typing.txt new/Werkzeug-2.1.2/requirements/typing.txt --- old/Werkzeug-2.1.1/requirements/typing.txt 2022-02-07 20:13:41.000000000 +0100 +++ new/Werkzeug-2.1.2/requirements/typing.txt 2022-04-28 17:53:45.000000000 +0200 @@ -5,17 +5,17 @@ # # pip-compile-multi # -mypy==0.931 +mypy==0.950 # via -r requirements/typing.in mypy-extensions==0.4.3 # via mypy -tomli==2.0.0 +tomli==2.0.1 # via mypy -types-contextvars==2.4.2 +types-contextvars==2.4.5 # via -r requirements/typing.in -types-dataclasses==0.6.4 +types-dataclasses==0.6.5 # via -r requirements/typing.in -types-setuptools==57.4.9 +types-setuptools==57.4.14 # via -r requirements/typing.in -typing-extensions==4.0.1 +typing-extensions==4.2.0 # via mypy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/setup.cfg new/Werkzeug-2.1.2/setup.cfg --- old/Werkzeug-2.1.1/setup.cfg 2022-04-01 18:00:45.271357000 +0200 +++ new/Werkzeug-2.1.2/setup.cfg 2022-04-28 19:39:13.677677000 +0200 @@ -44,6 +44,8 @@ testpaths = tests filterwarnings = error +markers = + dev_server: tests that start the dev server [coverage:run] branch = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/Werkzeug.egg-info/PKG-INFO new/Werkzeug-2.1.2/src/Werkzeug.egg-info/PKG-INFO --- old/Werkzeug-2.1.1/src/Werkzeug.egg-info/PKG-INFO 2022-04-01 18:00:44.000000000 +0200 +++ new/Werkzeug-2.1.2/src/Werkzeug.egg-info/PKG-INFO 2022-04-28 19:39:13.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Werkzeug -Version: 2.1.1 +Version: 2.1.2 Summary: The comprehensive WSGI web application library. Home-page: https://palletsprojects.com/p/werkzeug/ Author: Armin Ronacher diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/__init__.py new/Werkzeug-2.1.2/src/werkzeug/__init__.py --- old/Werkzeug-2.1.1/src/werkzeug/__init__.py 2022-04-01 18:00:05.000000000 +0200 +++ new/Werkzeug-2.1.2/src/werkzeug/__init__.py 2022-04-28 19:38:40.000000000 +0200 @@ -3,4 +3,4 @@ from .wrappers import Request as Request from .wrappers import Response as Response -__version__ = "2.1.1" +__version__ = "2.1.2" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/_internal.py new/Werkzeug-2.1.2/src/werkzeug/_internal.py --- old/Werkzeug-2.1.1/src/werkzeug/_internal.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/_internal.py 2022-04-25 20:08:23.000000000 +0200 @@ -523,8 +523,8 @@ injecting_start_response("200 OK", [("Content-Type", "text/html")]) return [ f"""\ -<!DOCTYPE html> -<html> +<!doctype html> +<html lang=en> <head> <title>About Werkzeug</title> <style type="text/css"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/datastructures.py new/Werkzeug-2.1.2/src/werkzeug/datastructures.py --- old/Werkzeug-2.1.1/src/werkzeug/datastructures.py 2022-04-01 17:34:08.000000000 +0200 +++ new/Werkzeug-2.1.2/src/werkzeug/datastructures.py 2022-04-25 20:08:23.000000000 +0200 @@ -2036,7 +2036,10 @@ elif value is True: self[key] = None else: - self[key] = type(value) + if type is not None: + self[key] = type(value) + else: + self[key] = value def _del_cache_value(self, key): """Used internally by the accessor properties.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/datastructures.pyi new/Werkzeug-2.1.2/src/werkzeug/datastructures.pyi --- old/Werkzeug-2.1.1/src/werkzeug/datastructures.pyi 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/datastructures.pyi 2022-04-24 19:29:53.000000000 +0200 @@ -20,6 +20,7 @@ from typing import Type from typing import TypeVar from typing import Union +from _typeshed import SupportsKeysAndGetItem from _typeshed.wsgi import WSGIEnvironment from typing_extensions import Literal @@ -96,9 +97,12 @@ def __delitem__(self, key: K) -> None: ... def clear(self) -> None: ... def popitem(self) -> Tuple[K, V]: ... - def update( - self, *args: Union[Mapping[K, V], Iterable[Tuple[K, V]]], **kwargs: V - ) -> None: ... + @overload + def update(self, __m: SupportsKeysAndGetItem[K, V], **kwargs: V) -> None: ... + @overload + def update(self, __m: Iterable[Tuple[K, V]], **kwargs: V) -> None: ... + @overload + def update(self, **kwargs: V) -> None: ... class TypeConversionDict(Dict[K, V]): @overload @@ -274,11 +278,16 @@ def __setitem__(self, key: int, value: Tuple[str, HV]) -> None: ... @overload def __setitem__(self, key: slice, value: Iterable[Tuple[str, HV]]) -> None: ... + @overload def update( - self, - *args: Union[Mapping[str, HV], Iterable[Tuple[str, HV]]], - **kwargs: Union[HV, Iterable[HV]], + self, __m: SupportsKeysAndGetItem[str, HV], **kwargs: Union[HV, Iterable[HV]] + ) -> None: ... + @overload + def update( + self, __m: Iterable[Tuple[str, HV]], **kwargs: Union[HV, Iterable[HV]] ) -> None: ... + @overload + def update(self, **kwargs: Union[HV, Iterable[HV]]) -> None: ... def to_wsgi_list(self) -> List[Tuple[str, str]]: ... def copy(self) -> Headers: ... def __copy__(self) -> Headers: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/debug/repr.py new/Werkzeug-2.1.2/src/werkzeug/debug/repr.py --- old/Werkzeug-2.1.1/src/werkzeug/debug/repr.py 2021-02-12 19:11:39.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/debug/repr.py 2022-04-24 20:02:20.000000000 +0200 @@ -83,8 +83,8 @@ inner: str, obj: object, base: t.Union[t.Type, t.Tuple[t.Type, ...]] ) -> str: if isinstance(base, tuple): - for base in base: - if type(obj) is base: + for cls in base: + if type(obj) is cls: return inner elif type(obj) is base: return inner diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/debug/tbtools.py new/Werkzeug-2.1.2/src/werkzeug/debug/tbtools.py --- old/Werkzeug-2.1.1/src/werkzeug/debug/tbtools.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/debug/tbtools.py 2022-04-28 17:53:45.000000000 +0200 @@ -12,8 +12,8 @@ from .console import Console HEADER = """\ -<!DOCTYPE html> -<html> +<!doctype html> +<html lang=en> <head> <title>%(title)s // Werkzeug Debugger</title> <link rel="stylesheet" href="?__debugger__=yes&cmd=resource&f=style.css"> @@ -375,7 +375,7 @@ def render_html(self, mark_library: bool) -> str: context = 5 lines = linecache.getlines(self.filename) - line_idx = self.lineno - 1 + line_idx = self.lineno - 1 # type: ignore[operator] start_idx = max(0, line_idx - context) stop_idx = min(len(lines), line_idx + context + 1) rendered_lines = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/exceptions.py new/Werkzeug-2.1.2/src/werkzeug/exceptions.py --- old/Werkzeug-2.1.1/src/werkzeug/exceptions.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/exceptions.py 2022-04-25 20:08:23.000000000 +0200 @@ -111,7 +111,8 @@ ) -> str: """Get the HTML body.""" return ( - '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n' + "<!doctype html>\n" + "<html lang=en>\n" f"<title>{self.code} {escape(self.name)}</title>\n" f"<h1>{escape(self.name)}</h1>\n" f"{self.get_description(environ)}\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/local.py new/Werkzeug-2.1.2/src/werkzeug/local.py --- old/Werkzeug-2.1.1/src/werkzeug/local.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/local.py 2022-04-24 19:29:53.000000000 +0200 @@ -280,7 +280,7 @@ if self.fallback is None: raise - fallback = self.fallback.__get__(instance, owner) # type: ignore + fallback = self.fallback.__get__(instance, owner) if self.is_attr: # __class__ and __doc__ are attributes, not methods. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/middleware/lint.py new/Werkzeug-2.1.2/src/werkzeug/middleware/lint.py --- old/Werkzeug-2.1.1/src/werkzeug/middleware/lint.py 2022-01-29 19:37:01.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/middleware/lint.py 2022-04-25 20:08:23.000000000 +0200 @@ -117,7 +117,7 @@ class GuardedWrite: - def __init__(self, write: t.Callable[[bytes], None], chunks: t.List[int]) -> None: + def __init__(self, write: t.Callable[[bytes], object], chunks: t.List[int]) -> None: self._write = write self._chunks = chunks diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/routing.py new/Werkzeug-2.1.2/src/werkzeug/routing.py --- old/Werkzeug-2.1.1/src/werkzeug/routing.py 2022-03-16 16:04:16.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/routing.py 2022-04-24 19:29:53.000000000 +0200 @@ -882,11 +882,9 @@ self._trace.append((False, "/")) self._build: t.Callable[..., t.Tuple[str, str]] - self._build = self._compile_builder(False).__get__(self, None) # type: ignore + self._build = self._compile_builder(False).__get__(self, None) self._build_unknown: t.Callable[..., t.Tuple[str, str]] - self._build_unknown = self._compile_builder(True).__get__( # type: ignore - self, None - ) + self._build_unknown = self._compile_builder(True).__get__(self, None) if self.build_only: return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/serving.py new/Werkzeug-2.1.2/src/werkzeug/serving.py --- old/Werkzeug-2.1.1/src/werkzeug/serving.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/serving.py 2022-04-25 20:08:23.000000000 +0200 @@ -265,13 +265,29 @@ self.send_header(key, value) header_keys.add(key.lower()) - if "content-length" not in header_keys: - if self.protocol_version >= "HTTP/1.1": - chunk_response = True - self.send_header("Transfer-Encoding", "chunked") - else: - self.send_header("Connection", "close") + # Use chunked transfer encoding if there is no content + # length. Do not use for 1xx and 204 responses. 304 + # responses and HEAD requests are also excluded, which + # is the more conservative behavior and matches other + # parts of the code. + # https://httpwg.org/specs/rfc7230.html#rfc.section.3.3.1 + if ( + not ( + "content-length" in header_keys + or environ["REQUEST_METHOD"] == "HEAD" + or (100 <= code < 200) + or code in {204, 304} + ) + and self.protocol_version >= "HTTP/1.1" + ): + chunk_response = True + self.send_header("Transfer-Encoding", "chunked") + # Always close the connection. This disables HTTP/1.1 + # keep-alive connections. They aren't handled well by + # Python's http.server because it doesn't know how to + # drain the stream before the next request line. + self.send_header("Connection", "close") self.end_headers() assert isinstance(data, bytes), "applications must write bytes" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/test.py new/Werkzeug-2.1.2/src/werkzeug/test.py --- old/Werkzeug-2.1.1/src/werkzeug/test.py 2022-03-17 17:44:34.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/test.py 2022-04-28 17:53:45.000000000 +0200 @@ -67,6 +67,7 @@ stream: t.IO[bytes] = BytesIO() total_length = 0 on_disk = False + write_binary: t.Callable[[bytes], int] if use_tempfile: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/testapp.py new/Werkzeug-2.1.2/src/werkzeug/testapp.py --- old/Werkzeug-2.1.1/src/werkzeug/testapp.py 2022-01-29 19:37:01.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/testapp.py 2022-04-25 20:08:23.000000000 +0200 @@ -60,8 +60,8 @@ TEMPLATE = """\ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> +<!doctype html> +<html lang=en> <title>WSGI Information</title> <style type="text/css"> @import url(https://fonts.googleapis.com/css?family=Ubuntu); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/src/werkzeug/utils.py new/Werkzeug-2.1.2/src/werkzeug/utils.py --- old/Werkzeug-2.1.1/src/werkzeug/utils.py 2022-03-17 17:44:34.000000000 +0100 +++ new/Werkzeug-2.1.2/src/werkzeug/utils.py 2022-04-25 20:08:23.000000000 +0200 @@ -273,13 +273,15 @@ from .urls import iri_to_uri location = iri_to_uri(location, safe_conversion=True) + response = Response( # type: ignore - '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n' + "<!doctype html>\n" + "<html lang=en>\n" "<title>Redirecting...</title>\n" "<h1>Redirecting...</h1>\n" - "<p>You should be redirected automatically to target URL: " + "<p>You should be redirected automatically to the target URL: " f'<a href="{html.escape(location)}">{display_location}</a>. If' - " not click the link.", + " not, click the link.\n", code, mimetype="text/html", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/middleware/test_http_proxy.py new/Werkzeug-2.1.2/tests/middleware/test_http_proxy.py --- old/Werkzeug-2.1.1/tests/middleware/test_http_proxy.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/middleware/test_http_proxy.py 2022-04-28 17:53:45.000000000 +0200 @@ -6,6 +6,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_http_proxy(standard_app): app = ProxyMiddleware( Response("ROOT"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/res/index.html new/Werkzeug-2.1.2/tests/res/index.html --- old/Werkzeug-2.1.1/tests/res/index.html 2021-02-12 19:11:39.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/res/index.html 2022-04-25 20:08:23.000000000 +0200 @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/test_datastructures.py new/Werkzeug-2.1.2/tests/test_datastructures.py --- old/Werkzeug-2.1.1/tests/test_datastructures.py 2022-03-31 22:58:53.000000000 +0200 +++ new/Werkzeug-2.1.2/tests/test_datastructures.py 2022-04-25 20:08:23.000000000 +0200 @@ -973,6 +973,8 @@ assert cc.no_cache is None cc.no_cache = None assert cc.no_cache is None + cc.no_cache = False + assert cc.no_cache is False class TestContentSecurityPolicy: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/test_debug.py new/Werkzeug-2.1.2/tests/test_debug.py --- old/Werkzeug-2.1.1/tests/test_debug.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/test_debug.py 2022-04-28 17:53:45.000000000 +0200 @@ -247,6 +247,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") @pytest.mark.parametrize("crash", (True, False)) +@pytest.mark.dev_server def test_basic(dev_server, crash): c = dev_server(use_debugger=True) r = c.request("/crash" if crash else "") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/test_exceptions.py new/Werkzeug-2.1.2/tests/test_exceptions.py --- old/Werkzeug-2.1.1/tests/test_exceptions.py 2022-01-29 19:37:01.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/test_exceptions.py 2022-04-25 20:08:23.000000000 +0200 @@ -1,4 +1,5 @@ from datetime import datetime +from html import escape import pytest @@ -146,3 +147,18 @@ def test_description_none(): HTTPException().get_response() + + +@pytest.mark.parametrize( + "cls", + sorted( + (e for e in HTTPException.__subclasses__() if e.code), + key=lambda e: e.code, # type: ignore + ), +) +def test_response_body(cls): + exc = cls() + response_body = exc.get_body() + assert response_body.startswith("<!doctype html>\n<html lang=en>\n") + assert f"{exc.code} {escape(exc.name)}" in response_body + assert exc.get_description() in response_body diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/test_serving.py new/Werkzeug-2.1.2/tests/test_serving.py --- old/Werkzeug-2.1.1/tests/test_serving.py 2022-02-18 01:24:02.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/test_serving.py 2022-04-28 17:53:45.000000000 +0200 @@ -35,6 +35,7 @@ ), ], ) +@pytest.mark.dev_server def test_server(tmp_path, dev_server, kwargs: dict): if kwargs.get("hostname") == "unix": kwargs["hostname"] = f"unix://{tmp_path / 'test.sock'}" @@ -46,6 +47,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_untrusted_host(standard_app): r = standard_app.request( "http://missing.test:1337/index.html#ignore", @@ -59,6 +61,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_double_slash_path(standard_app): r = standard_app.request("//double-slash") assert "double-slash" not in r.json["HTTP_HOST"] @@ -66,6 +69,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_500_error(standard_app): r = standard_app.request("/crash") assert r.status == 500 @@ -73,6 +77,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_ssl_dev_cert(tmp_path, dev_server): client = dev_server(ssl_context=make_ssl_devcert(tmp_path)) r = client.request() @@ -80,6 +85,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_ssl_object(dev_server): client = dev_server(ssl_context="custom") r = client.request() @@ -91,6 +97,7 @@ @pytest.mark.skipif( os.name == "nt" and "CI" in os.environ, reason="unreliable on Windows during CI" ) +@pytest.mark.dev_server def test_reloader_sys_path(tmp_path, dev_server, reloader_type): """This tests the general behavior of the reloader. It also tests that fixing an import error triggers a reload, not just Python @@ -129,6 +136,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_wrong_protocol(standard_app): """An HTTPS request to an HTTP server doesn't show a traceback. https://github.com/pallets/werkzeug/pull/838 @@ -142,6 +150,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_content_type_and_length(standard_app): r = standard_app.request() assert "CONTENT_TYPE" not in r.json @@ -159,6 +168,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") @pytest.mark.parametrize("send_length", [False, True]) +@pytest.mark.dev_server def test_chunked_request(monkeypatch, dev_server, send_length): stream, length, boundary = stream_encode_multipart( { @@ -200,6 +210,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_multiple_headers_concatenated(standard_app): """A header key can be sent multiple times. The server will join all the values with commas. @@ -224,6 +235,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_multiline_header_folding(standard_app): """A header value can be split over multiple lines with a leading tab. The server will remove the newlines and preserve the tabs. @@ -242,6 +254,7 @@ @pytest.mark.parametrize("endpoint", ["", "crash"]) +@pytest.mark.dev_server def test_streaming_close_response(dev_server, endpoint): """When using HTTP/1.0, chunked encoding is not supported. Fall back to Connection: close, but this allows no reliable way to @@ -252,6 +265,7 @@ assert r.data == "".join(str(x) + "\n" for x in range(5)).encode() +@pytest.mark.dev_server def test_streaming_chunked_response(dev_server): """When using HTTP/1.1, use Transfer-Encoding: chunked for streamed responses, since it can distinguish the end of the response without @@ -265,6 +279,7 @@ @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") +@pytest.mark.dev_server def test_streaming_chunked_truncation(dev_server): """When using HTTP/1.1, chunked encoding allows the client to detect content truncated by a prematurely closed connection. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Werkzeug-2.1.1/tests/test_utils.py new/Werkzeug-2.1.2/tests/test_utils.py --- old/Werkzeug-2.1.1/tests/test_utils.py 2022-03-17 17:44:34.000000000 +0100 +++ new/Werkzeug-2.1.2/tests/test_utils.py 2022-04-25 20:08:23.000000000 +0200 @@ -14,18 +14,43 @@ def test_redirect(): resp = utils.redirect("/f????b??r") - assert b"/f%C3%BC%C3%BCb%C3%A4r" in resp.get_data() assert resp.headers["Location"] == "/f%C3%BC%C3%BCb%C3%A4r" assert resp.status_code == 302 + assert resp.get_data() == ( + b"<!doctype html>\n" + b"<html lang=en>\n" + b"<title>Redirecting...</title>\n" + b"<h1>Redirecting...</h1>\n" + b"<p>You should be redirected automatically to the target URL: " + b'<a href="/f%C3%BC%C3%BCb%C3%A4r">/f\xc3\xbc\xc3\xbcb\xc3\xa4r</a>. ' + b"If not, click the link.\n" + ) resp = utils.redirect("http://???.net/", 307) - assert b"http://xn--n3h.net/" in resp.get_data() assert resp.headers["Location"] == "http://xn--n3h.net/" assert resp.status_code == 307 + assert resp.get_data() == ( + b"<!doctype html>\n" + b"<html lang=en>\n" + b"<title>Redirecting...</title>\n" + b"<h1>Redirecting...</h1>\n" + b"<p>You should be redirected automatically to the target URL: " + b'<a href="http://xn--n3h.net/">http://\xe2\x98\x83.net/</a>. ' + b"If not, click the link.\n" + ) resp = utils.redirect("http://example.com/", 305) assert resp.headers["Location"] == "http://example.com/" assert resp.status_code == 305 + assert resp.get_data() == ( + b"<!doctype html>\n" + b"<html lang=en>\n" + b"<title>Redirecting...</title>\n" + b"<h1>Redirecting...</h1>\n" + b"<p>You should be redirected automatically to the target URL: " + b'<a href="http://example.com/">http://example.com/</a>. ' + b"If not, click the link.\n" + ) def test_redirect_xss():