Werkzeug v2.0.0 Release Notes
-
๐ Released 2021-05-11
- ๐ Drop support for Python 2 and 3.5. :pr:
1693
- ๐ Deprecate :func:
utils.format_string
, use :class:string.Template
instead. :issue:1756
- ๐ Deprecate :func:
utils.bind_arguments
and :func:utils.validate_arguments
, use :meth:Signature.bind
and :func:inspect.signature
instead. :issue:1757
- ๐ Deprecate :class:
utils.HTMLBuilder
. :issue:1761
- ๐ Deprecate :func:
utils.escape
and :func:utils.unescape
, use MarkupSafe instead. :issue:1758
- ๐ Deprecate the undocumented
python -m werkzeug.serving
CLI. :issue:1834
- ๐ Deprecate the
environ["werkzeug.server.shutdown"]
function that is available when running the development server. :issue:1752
- ๐ Deprecate the
useragents
module and the built-in user agent parser. Use a dedicated parser library instead by subclassinguser_agent.UserAgent
and settingRequest.user_agent_class
. :issue:2078
- ๐ Remove the unused, internal
posixemulation
module. :issue:1759
- All
datetime
values are timezone-aware withtzinfo=timezone.utc
. This applies to anything usinghttp.parse_date
:Request.date
,.if_modified_since
,.if_unmodified_since
;Response.date
,.expires
,.last_modified
,.retry_after
;parse_if_range_header
, andIfRange.date
. When comparing values, the other values must also be aware, or these values must be made naive. When passing parameters or setting attributes, naive values are still assumed to be in UTC. :pr:2040
- ๐ Merge all request and response wrapper mixin code into single
Request
andResponse
classes. Using the mixin classes is no longer necessary and will show a deprecation warning. Checkingisinstance
orissubclass
againstBaseRequest
andBaseResponse
will show a deprecation warning and check againstRequest
orResponse
instead. :issue:1963
- ๐ JSON support no longer uses simplejson if it's installed. To use
another JSON module, override
Request.json_module
andResponse.json_module
. :pr:1766
-
Response.get_json()
no longer caches the result, and thecache
parameter is removed. :issue:1698
-
Response.freeze()
generates anETag
header if one is not set. Theno_etag
parameter (which usually wasn't visible anyway) is no longer used. :issue:1963
- ๐ Add a
url_scheme
argument to :meth:~routing.MapAdapter.build
to override the bound scheme. :pr:1721
- ๐ Passing an empty list as a query string parameter to
build()
won't append an unnecessary?
. Also drop any number ofNone
items in a list. :issue:1992
- โ
When passing a
Headers
object to a test client method orEnvironBuilder
, multiple values for a key are joined into one comma separated value. This matches the HTTP spec on multi-value headers. :issue:1655
- Setting
Response.status
andstatus_code
uses identical parsing and error checking. :issue:1658
, :pr:1728
-
MethodNotAllowed
andRequestedRangeNotSatisfiable
take aresponse
kwarg, consistent with other HTTP errors. :pr:1748
- The response generated by :exc:
~exceptions.Unauthorized
produces oneWWW-Authenticate
header per value inwww_authenticate
, rather than joining them into a single value, to improve interoperability with browsers and other clients. :pr:1755
- If
parse_authorization_header
can't decode the header value, it returnsNone
instead of raising aUnicodeDecodeError
. :issue:1816
- The debugger no longer uses jQuery. :issue:
1807
- โ
The test client includes the query string in
REQUEST_URI
andRAW_URI
. :issue:1781
- Switch the parameter order of
default_stream_factory
to match the order used when calling it. :pr:1085
- Add
send_file
function to generate a response that serves a file. Adapted from Flask's implementation. :issue:265
, :pr:1850
- Add
send_from_directory
function to safely serve an untrusted path within a trusted directory. Adapted from Flask's implementation. :issue:1880
-
send_file
takesdownload_name
, which is passed even ifas_attachment=False
by usingContent-Disposition: inline
.download_name
replaces Flask'sattachment_filename
. :issue:1869
-
send_file
setsconditional=True
andmax_age=None
by default.Cache-Control
is set tono-cache
ifmax_age
is not set, otherwisepublic
. This tells browsers to validate conditional requests instead of using a timed cache.max_age=None
replaces Flask'scache_timeout=43200
. :issue:1882
-
send_file
can be called withetag="string"
to set a custom ETag instead of generating one.etag
replaces Flask'sadd_etags
. :issue:1868
-
send_file
sets theContent-Encoding
header if an encoding is returned when guessingmimetype
fromdownload_name
. :pr:3896
- Update the defaults used by
generate_password_hash
. Increase PBKDF2 iterations to 260000 from 150000. Increase salt length to 16 from 8. Usesecrets
module to generate salt. :pr:1935
- The reloader doesn't crash if
sys.stdin
is somehowNone
. :pr:1915
- Add arguments to
delete_cookie
to matchset_cookie
and the attributes modern browsers expect. :pr:1889
- ๐
utils.cookie_date
is deprecated, useutils.http_date
instead. The value forSet-Cookie expires
is no longer "-" delimited. :pr:2040
- Use
request.headers
instead ofrequest.environ
to look up header attributes. :pr:1808
- โ
The test
Client
request methods (client.get
, etc.) always return an instance ofTestResponse
. In addition to the normal behavior ofResponse
, this class providesrequest
with the request that produced the response, andhistory
to track intermediate responses whenfollow_redirects
is used. :issue:763, 1894
- โ
The test
Client
request methods takes anauth
parameter to add anAuthorization
header. It can be anAuthorization
object or a(username, password)
tuple forBasic
auth. :pr:1809
- โ
Calling
response.close()
on a response from the testClient
will close the request input stream. This matches file behavior and can prevent aResourceWarning
in some cases. :issue:1785
-
EnvironBuilder.from_environ
decodes values encoded for WSGI, to avoid double encoding the new values. :pr:1959
- 0๏ธโฃ The default stat reloader will watch Python files under
non-system/virtualenv
sys.path
entries, which should contain most user code. It will also watch all Python files under directories given inextra_files
. :pr:1945
- The reloader ignores
__pycache__
directories again. :pr:1945
-
run_simple
takesexclude_patterns
a list offnmatch
patterns that will not be scanned by the reloader. :issue:1333
- Cookie names are no longer unquoted. This was against :rfc:
6265
and potentially allowed setting__Secure
prefixed cookies. :pr:1965
- Fix some word matches for user agent platform when the word can be a
substring. :issue:
1923
- ๐ The development server logs ignored SSL errors. :pr:
1967
- Temporary files for form data are opened in
rb+
instead ofwb+
mode for better compatibility with some libraries. :issue:1961
- ๐ Use SHA-1 instead of MD5 for generating ETags and the debugger pin,
and in some tests. MD5 is not available in some environments, such
as FIPS 140. This may invalidate some caches since the ETag will be
different. :issue:
1897
- Add
Cross-Origin-Opener-Policy
andCross-Origin-Embedder-Policy
response header properties. :pr:2008
-
run_simple
tries to show a valid IP address when binding to all addresses, instead of0.0.0.0
or::
. It also warns about not running the development server in production in this case. :issue:1964
- ๐ฒ Colors in the development server log are displayed if Colorama is
installed on Windows. For all platforms, style support no longer
requires Click. :issue:
1832
- A range request for an empty file (or other data with length 0) will
return a 200 response with the empty file instead of a 416 error.
:issue:
1937
- New sans-IO base classes for
Request
andResponse
have been extracted to contain all the behavior that is not WSGI or IO dependent. These are not a public API, they are part of an ongoing refactor to let ASGI frameworks use Werkzeug. :pr:2005
- ๐จ Parsing
multipart/form-data
has been refactored to use sans-io patterns. This should also make parsing forms with large binary file uploads significantly faster. :issue:1788, 875
-
LocalProxy
matches the current Python data model special methods, including all r-ops, in-place ops, and async.__class__
is proxied, so the proxy will look like the object in more cases, includingisinstance
. Useissubclass(type(obj), LocalProxy)
to check if an object is actually a proxy. :issue:1754
-
Local
usesContextVar
on Python 3.7+ instead ofthreading.local
. :pr:1778
-
request.values
does not includeform
for GET requests (even though GET bodies are undefined). This prevents bad caching proxies from caching form data instead of query strings. :pr:2037
- The development server adds the underlying socket to
environ
aswerkzeug.socket
. This is non-standard and specific to the dev server, other servers may expose this under their own key. It is useful for handling a WebSocket upgrade request. :issue:2052
- โฌ๏ธ URL matching assumes
websocket=True
mode for WebSocket upgrade requests. :issue:2052
- โก๏ธ Updated
UserAgentParser
to handle more cases. :issue:1971
-
werzeug.DechunkedInput.readinto
will not read beyond the size of the buffer. :issue:2021
- Fix connection reset when exceeding max content size. :pr:
2051
-
pbkdf2_hex
,pbkdf2_bin
, andsafe_str_cmp
are deprecated.hashlib
andhmac
provide equivalents. :pr:2083
-
invalidate_cached_property
is deprecated. Usedel obj.name
instead. :pr:2084
- ๐
Href
is deprecated. Usewerkzeug.routing
instead. :pr:2085
-
Request.disable_data_descriptor
is deprecated. Create the request withshallow=True
instead. :pr:2085
- ๐
HTTPException.wrap
is deprecated. Create a subclass manually instead. :pr:2085
- ๐ Drop support for Python 2 and 3.5. :pr: