CHANGES.rst
.. currentmodule:: werkzeug
Released 2026-04-02
Request.host and get_host return the empty string if the header is
missing or has invalid characters. :issue:3142Released 2026-03-23
parse_list_header preserves partially quoted items, discards empty
items, and returns empty for unclosed quoted values. :pr:3128WWWAuthenticate.to_header does not produce a trailing space when there
are no parameters. :issue:3127Transfer-Encoding is parsed as a set. :pr:3134Request.host, get_host, and host_is_trusted validate the
characters of the value. An empty value is no longer allowed. A Unix socket
server address is ignored. The trusted_list argument to
host_is_trusted is optional. :pr:31133088Response.make_conditional sets the Accept-Ranges header even if it
is not a satisfiable range request. :issue:3108merge_slashes merges any number of consecutive slashes. :issue:3121Released 2026-02-19
safe_join on Windows does not allow special devices names in
multi-segment paths. :ghsa:29vq-49wr-vm6xResponse.make_conditional sets the Accept-Ranges header even if it
is not a satisfiable range request. :issue:3108Released 2026-01-08
safe_join on Windows does not allow more special device names, regardless
of extension or surrounding spaces. :ghsa:87hc-h4r5-73f7\r\n sequence at a chunk boundary.
This fixes the previous attempt, which caused incorrect content lengths.
:issue:3065 :issue:3077AttributeError when initializing DebuggedApplication with
pin_security=False. :issue:3075Released 2025-11-28
safe_join on Windows does not allow special device names. This prevents
reading from these when using send_from_directory. secure_filename
already prevented writing to these. :ghsa:hgf8-39gv-g3f23020\r\n sequence at a chunk boundary.
:issue:30653054Request.json annotation is more accurate. :issue:30673044HTTPException.get_response annotation and doc better conveys the
distinction between WSGI and sans-IO responses. :issue:3056Released 2024-11-08
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:2994Host 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:2993Released 2024-11-04
TypeConversionDict.get to allow the type
parameter to be a callable. :issue:2988Headers does not inherit from MutableMapping, as it is does not
exactly match that interface. :issue:2989Released 2024-11-01
str(Request.headers) to always appear empty.
:issue:2985Released 2024-10-31
Drop support for Python 3.8. :pr:2966
Remove previously deprecated code. :pr:2967
Request.max_form_memory_size defaults to 500kB instead of unlimited.
Non-file form fields over this size will cause a RequestEntityTooLarge
error. :issue:2964
OrderedMultiDict and ImmutableOrderedMultiDict are deprecated.
Use MultiDict and ImmutableMultiDict instead. :issue:2968
Behavior of properties on request.cache_control and
response.cache_control has been significantly adjusted.
str | None. Setting properties will convert
the value to a string. Setting a property to False is equivalent to
setting it to None. Getting typed properties will return None if
conversion raises ValueError, rather than the string. :issue:2980max_age is None if present without a value, rather than -1.
:issue:2980no_cache is a boolean for requests, it is True instead of
"*" when present. It remains a string for responses. :issue:2980max_stale is True if present without a value, rather
than "*". :issue:2980no_transform is a boolean. Previously it was mistakenly always
None. :issue:2881min_fresh is None if present without a value, rather than
"*". :issue:2881private is True if present without a value, rather than "*".
:issue:2980must_understand property. :issue:2881stale_while_revalidate, and stale_if_error
properties. :issue:29482881Support Cookie CHIPS (Partitioned Cookies). :issue:2797
Add 421 MisdirectedRequest HTTP exception. :issue:2850
Increase default work factor for PBKDF2 to 1,000,000 iterations.
:issue:2969
Inline annotations for datastructures, removing stub files.
:issue:2970
MultiDict.getlist catches TypeError in addition to ValueError
when doing type conversion. :issue:2976
Implement | and |= operators for MultiDict, Headers, and
CallbackDict, and disallow |= on immutable types. :issue:2977
Released 2024-10-25
max_form_memory_size is applied when parsing large non-file
fields. :ghsa:q34m-jh98-gwm2safe_join catches certain paths on Windows that were not caught by
ntpath.isabs on Python < 3.11. :ghsa:f9vj-2wh5-fj8jReleased 2024-10-24
294529522955SharedDataMiddleware. :issue:29582957Released 2024-08-21
multipart/x-www-form-urlencoded data with
invalid UTF-8 bytes in the body results in no form data parsed rather than a
413 error. :issue:2930parse_options_header performance when parsing unterminated
quoted string values. :issue:29042916SSLEOFError due to issue in Python < 3.13.
:issue:29262918Released 2024-05-05
localhost, .localhost, 127.0.0.1, or the specified
hostname when running the dev server, to make debugger requests. Additional
hosts can be added by using the debugger middleware directly. The debugger
UI makes requests using the full URL rather than only the path.
:ghsa:2g68-c3qc-8985"" is in sys.path. :pr:2823adhoc dev certs. :pr:2891itms-services URIs correctly, rather
than using an overly-broad workaround in Werkzeug that caused some redirect
URIs to be passed on without encoding. :issue:2828Rule.endpoint and other uses of endpoint is
Any. :issue:2836"" is in sys.path. :pr:2823Released 2024-04-01
merge_slashes to False results in NotFound for
repeated-slash requests against single slash routes. :issue:2834TypeError in TypeConversionDict.get() to match
ValueError. :issue:2843response_wrapper type check in test client. :issue:2831MultiPartParser.parse more precise.
:issue:28402822Released 2023-10-24
Released 2023-09-30
2768__version__ attribute. Use feature detection, or
importlib.metadata.version("werkzeug"), instead. :issue:2770generate_password_hash uses scrypt by default. :issue:2769"werkzeug.profiler" item to the WSGI environ dictionary
passed to ProfilerMiddleware's filename_format function. It contains
the elapsed and time values for the profiled request. :issue:27752784Released 2023-11-08
Released 2023-08-14
flit_core instead of setuptools as build backend.27342761273427402750Accept q value can be a float without a decimal part. :issue:2751Released 2023-06-08
FileStorage.content_length does not fail if the form data did not provide a
value. :issue:2726Released 2023-06-07
2704Authorization.from_header. :issue:27172719routing.Map, a long IDNA server_name with a port does not fail
encoding. :issue:2700iri_to_uri shows a deprecation warning instead of an error when passing bytes.
:issue:2708Content-Length, only ASCII
digits are accepted rather than any format that Python's int and float
accept. :issue:2716Released 2023-05-08
Authorization.from_header and WWWAuthenticate.from_header detects tokens
that end with base64 padding (=). :issue:2685warnings.catch_warnings. :issue:2690max_form_parts restriction from standard form data parsing and only use
if for multipart content. :pr:2694Response will avoid converting the Location header in some cases to preserve
invalid URL schemes like itms-services. :issue:2691Released 2023-05-01
2658, 2675Path attribute is set to / by default again, to prevent clients
from falling back to RFC 6265's default-path behavior. :issue:2672, 2679Released 2023-04-28
Expires attribute correctly in the test client. :issue:2669max_content_length can only be enforced on streaming requests if the server
sets wsgi.input_terminated. :issue:2668Released 2023-04-27
26572659pyi files for datastructures type annotations. :issue:2660Authorization and WWWAuthenticate objects can be compared for equality.
:issue:2665Released 2023-04-25
Drop support for Python 3.7. :pr:2648
Remove previously deprecated code. :pr:2592
Passing bytes where strings are expected is deprecated, as well as the charset
and errors parameters in many places. Anywhere that was annotated, documented,
or tested to accept bytes shows a warning. Removing this artifact of the transition
from Python 2 to 3 removes a significant amount of overhead in instance checks and
encoding cycles. In general, always work with UTF-8, the modern HTML, URL, and HTTP
standards all strongly recommend this. :issue:2602
Deprecate the werkzeug.urls module, except for the uri_to_iri and
iri_to_uri functions. Use the urllib.parse library instead. :issue:2600
Update which characters are considered safe when using percent encoding in URLs,
based on the WhatWG URL Standard. :issue:2601
Update which characters are considered safe when using percent encoding for Unicode
filenames in downloads. :issue:2598
Deprecate the safe_conversion parameter of iri_to_uri. The Location
header is converted to IRI using the same process as everywhere else. :issue:2609
Deprecate werkzeug.wsgi.make_line_iter and make_chunk_iter. :pr:2613
Use modern packaging metadata with pyproject.toml instead of setup.cfg.
:pr:2574
Request.get_json() will raise a 415 Unsupported Media Type error if the
Content-Type header is not application/json, instead of a generic 400.
:issue:2550
A URL converter's part_isolating defaults to False if its regex contains
a /. :issue:2582
A custom converter's regex can have capturing groups without breaking the router.
:pr:2596
The reloader can pick up arguments to python like -X dev, and does not
require heuristics to determine how to reload the command. Only available
on Python >= 3.10. :issue:2589
The Watchdog reloader ignores file opened events. Bump the minimum version of
Watchdog to 2.3.0. :issue:2603
When using a Unix socket for the development server, the path can start with a dot.
:issue:2595
Increase default work factor for PBKDF2 to 600,000 iterations. :issue:2611
parse_options_header is 2-3 times faster. It conforms to :rfc:9110, some
invalid parts that were previously accepted are now ignored. :issue:1628
The is_filename parameter to unquote_header_value is deprecated. :pr:2614
Deprecate the extra_chars parameter and passing bytes to quote_header_value,
the allow_token parameter to dump_header, and the cls parameter and
passing bytes to parse_dict_header. :pr:2618
Improve parse_accept_header implementation. Parse according to :rfc:9110.
Discard items with invalid q values. :issue:1623
quote_header_value quotes the empty string. :pr:2618
dump_options_header skips None values rather than using a bare key.
:pr:2618
dump_header and dump_options_header will not quote a value if the key ends
with an asterisk *.
parse_dict_header will decode values with charsets. :pr:2618
Refactor the Authorization and WWWAuthenticate header data structures.
:issue:1769, :pr:2619
type, parameters, and token attributes. The
token attribute supports auth schemes that use a single opaque token rather
than key=value parameters, such as Bearer.dict anymore, although they still implement getting,
setting, and deleting auth[key] and auth.key syntax, as well as
auth.get(key) and key in auth.from_header class method. parse_authorization_header
and parse_www_authenticate_header are deprecated.WWWAuthenticate.set_basic and set_digest are deprecated.
Instead, an instance should be created and assigned to
response.www_authenticate.response.www_authenticate to set
multiple header values. However, accessing the property only returns the first
instance.Refactor parse_cookie and dump_cookie. :pr:2637
parse_cookie is up to 40% faster, dump_cookie is up to 60% faster.parse_cookie and dump_cookie is deprecated. The
dump_cookie charset parameter is deprecated.dump_cookie allows domain values that do not include a dot ., and
strips off a leading dot.dump_cookie does not set path="/" unnecessarily by default.Refactor the test client cookie implementation. :issue:1060, 1680
cookie_jar attribute is deprecated. http.cookiejar is no longer used
for storage.domain and path parameters default to localhost and /.get_cookie method to inspect cookies.decoded_key and decoded_value attributes to match what the
app sees rather than the encoded values a client would see.server_name parameter to set_cookie and
delete_cookie is deprecated. Use the domain parameter instead.delete_cookie besides domain, path, and
value are deprecated.If request.max_content_length is set, it is checked immediately when accessing
the stream, and while reading from the stream in general, rather than only during
form parsing. :issue:1513
The development server, which must not be used in production, will exhaust the
request stream up to 10GB or 1000 reads. This allows clients to see a 413 error if
max_content_length is exceeded, instead of a "connection reset" failure.
:pr:2620
The development server discards header keys that contain underscores _, as they
are ambiguous with dashes - in WSGI. :pr:2622
secure_filename looks for more Windows reserved file names. :pr:2623
Update type annotation for best_match to make default parameter clearer.
:issue:2625
Multipart parser handles empty fields correctly. :issue:2632
The Map charset parameter and Request.url_charset property are
deprecated. Percent encoding in URLs must always represent UTF-8 bytes. Invalid
bytes are left percent encoded rather than replaced. :issue:2602
The Request.charset, Request.encoding_errors, Response.charset, and
Client.charset attributes are deprecated. Request and response data must always
use UTF-8. :issue:2602
Header values that have charset information only allow ASCII, UTF-8, and ISO-8859-1.
:pr:2614, 2641
Update type annotation for ProfilerMiddleware stream parameter.
:issue:2642
Use postponed evaluation of annotations. :pr:2644
The development server escapes ASCII control characters in decoded URLs before
logging the request to the terminal. :pr:2652
The FormDataParser parse_functions attribute and get_parse_func method,
and the invalid application/x-url-encoded content type, are deprecated.
:pr:2653
generate_password_hash supports scrypt. Plain hash methods are deprecated, only
scrypt and pbkdf2 are supported. :issue:2654
Released 2023-02-14
2533get_json specifies that return type is not optional when
silent=False. :issue:2508parse_content_range_header returns None for a value like bytes */-1
where the length is invalid, instead of raising an AssertionError. :issue:2531ResourceWarning related to the socket used by run_simple.
Remove prepare_socket, which now happens when creating the server. :issue:2421multipart/form-data requests with the test
client. :issue:25492529LimitedStream.read works correctly when wrapping a stream that may not return
the requested size in one read call. :issue:2558= is treated as an empty key and discarded,
rather than stripping the leading ==.RequestEntityTooLarge exception is raised on parsing. This mitigates a DoS
attack where a larger number of form/file parts would result in disproportionate
resource use.Released 2022-08-08
strict_slashes == False behaviour
whereby leaf-requests match branch rules and vice
versa. :pr:2489/ within converter arguments. :pr:2489werkzeug.routing to use the
import as syntax for explicitly re-exporting public attributes.
:pr:249324942480LocalProxy.__wrapped__ is always set to the wrapped object when
the proxy is unbound, fixing an issue in doctest that would cause it
to fail. :issue:2485ResourceWarning related to the socket used by
run_simple. :issue:2421Released 2022-07-27
/path/ will match a rule /path if strict
slashes mode is disabled for the rule. :issue:2467/2df does not match /<int>. :pr:24702471ValidationError to be importable from
werkzeug.routing. :issue:2465Released 2022-07-23
get_script_name, get_query_string,
peek_path_info, pop_path_info, and
extract_path_info. :pr:246124612419werkzeug.debug.preserve_context mechanism for
restoring context-local data for a request when running code in the
debug console. :pr:2439end_lineno
and end_col_offset are present on AST nodes. :issue:2425/ it must set the class variable part_isolating = False.
:pr:243310746266 that the case is not relevant. :issue:2442AnyConverter validates the value passed for it when building
URLs. :issue:23882407is_resource_modified and parse_cookie functions
based on WSGI versions. :issue:2408get_content_length function. :pr:24152450FileStorage accepts os.PathLike. :pr:2418Released 2022-04-28
Transfer-Encoding: chunked
for 1xx, 204, 304, and HEAD responses. :issue:2375<!doctype html> and <html lang=en>. :issue:2390cache_control attributes to False.
:issue:2379keep-alive connections in the development server, which
are not supported sufficiently by Python's http.server.
:issue:2397Released 2022-04-01
ResponseCacheControl.s_maxage converts its value to an int, like
max_age. :issue:2364Released 2022-03-28
Drop support for Python 3.6. :pr:2277
Using gevent or eventlet requires greenlet>=1.0 or PyPy>=7.3.7.
werkzeug.locals and contextvars will not work correctly with
older versions. :pr:2278
Remove previously deprecated code. :pr:2276
shutdown function from the WSGI
environ when running the development server. See the docs for
alternatives.Request and Response classes.useragents module is removed.
The user_agent module provides an interface that can be
subclassed to add a parser, such as ua-parser. By default it
only stores the whole string.TestResponse instances and can no
longer be treated as a tuple. All data is available as
properties on the response.locals.get_ident and related thread-local code from
locals, it no longer makes sense when moving to a
contextvars-based implementation.python -m werkzeug.serving CLI.has_key method on some mapping datastructures; use
key in data instead.Request.disable_data_descriptor is removed, pass
shallow=True instead.no_etag parameter from Response.freeze().HTTPException.wrap class method.cookie_date function. Use http_date instead.pbkdf2_hex, pbkdf2_bin, and safe_str_cmp
functions. Use equivalents in hashlib and hmac modules
instead.Href class.HTMLBuilder class.invalidate_cached_property function. Use
del obj.attr instead.bind_arguments and validate_arguments. Use
:meth:Signature.bind and :func:inspect.signature instead.detect_utf_encoding, it's built-in to json.loads.format_string, use :class:string.Template instead.escape and unescape. Use MarkupSafe instead.The multiple parameter of parse_options_header is
deprecated. :pr:2357
Rely on :pep:538 and :pep:540 to handle decoding file names
with the correct filesystem encoding. The filesystem module is
removed. :issue:1760
Default values passed to Headers are validated the same way
values added later are. :issue:1608
Setting CacheControl int properties, such as max_age, will
convert the value to an int. :issue:2230
Always use socket.fromfd when restarting the dev server.
:pr:2287
When passing a dict of URL values to Map.build, list values do
not filter out None or collapse to a single value. Passing a
MultiDict does collapse single items. This undoes a previous
change that made it difficult to pass a list, or None values in
a list, to custom URL converters. :issue:2249
run_simple shows instructions for dealing with "address already
in use" errors, including extra instructions for macOS. :pr:2321
Extend list of characters considered always safe in URLs based on
:rfc:3986. :issue:2319
Optimize the stat reloader to avoid watching unnecessary files in
more cases. The watchdog reloader is still recommended for
performance and accuracy. :issue:2141
The development server uses Transfer-Encoding: chunked for
streaming responses when it is configured for HTTP/1.1.
:issue:2090, 1327, :pr:2091
The development server uses HTTP/1.1, which enables keep-alive
connections and chunked streaming responses, when threaded or
processes is enabled. :pr:2323
cached_property works for classes with __slots__ if a
corresponding _cache_{name} slot is added. :pr:2332
Refactor the debugger traceback formatter to use Python's built-in
traceback module as much as possible. :issue:1753
The TestResponse.text property is a shortcut for
r.get_data(as_text=True), for convenient testing against text
instead of bytes. :pr:2337
safe_join ensures that the path remains relative if the trusted
directory is the empty string. :pr:2349
Percent-encoded newlines (%0a), which are decoded by WSGI
servers, are considered when routing instead of terminating the
match early. :pr:2350
The test client doesn't set duplicate headers for CONTENT_LENGTH
and CONTENT_TYPE. :pr:2348
append_slash_redirect handles PATH_INFO with internal
slashes. :issue:1972, :pr:2338
The default status code for append_slash_redirect is 308 instead
of 301. This preserves the request body, and matches a previous
change to strict_slashes in routing. :issue:2351
Fix ValueError: I/O operation on closed file. with the test
client when following more than one redirect. :issue:2353
Response.autocorrect_location_header is disabled by default.
The Location header URL will remain relative, and exclude the
scheme and domain, by default. :issue:2352
Request.get_json() will raise a 400 BadRequest error if the
Content-Type header is not application/json. This makes a
very common source of confusion more visible. :issue:2339
Released 2022-02-07
ProxyFix supports IPv6 addresses. :issue:2262Response.make_conditional,
HTTPException.get_response, and Map.bind_to_environ accepts
Request in addition to WSGIEnvironment for the first
parameter. :pr:2290Request.user_agent_class. :issue:2273LocalProxy.__class__ and __doc__ on an unbound
proxy returns the fallback value instead of a method object.
:issue:2188RAW_URI and REQUEST_URI
correctly. :issue:2151Released 2021-10-05
Connection header when routing
WebSocket requests. :issue:21312150MultiDict.update to accept iterable
values :pr:2142merge_slash=True
for Rule.match. :issue:2157CombinedMultiDict.to_dict with flat=False considers all
component dicts when building value lists. :issue:2189send_file only sets a detected Content-Encoding if
as_attachment is disabled to avoid browsers saving
decompressed .tar.gz files. :issue:2149TypeConversionDict.get to not return an
Optional value if both default and type are not
None. :issue:2169Iterable[RuleFactory] instead of Iterable[Rule] for the
rules parameter. :issue:2183FileStorage.__getattr__
:issue:2155SameSite set to Strict
instead of None to be compatible with modern browser security.
:issue:2156IO[bytes] and IO[str] instead of
BinaryIO and TextIO for wider type compatibility.
:issue:213021582212CallbackDict, because it is not
utilizing a bound TypeVar. :issue:223522372239ProcessPoolExecutor.
:issue:2217Released 2021-05-17
send_file max_age callable. Don't
pass pathlib.Path to max_age. :issue:211921222123cached_property is generic over its return type, properties
decorated with it report the correct type. :issue:21132125headers.get with a string
default will always return a string. :issue:2128HTTPException.description is not a string,
get_description will convert it to a string. :issue:2115Released 2021-05-11
1693utils.format_string, use :class:string.Template
instead. :issue:1756utils.bind_arguments and
:func:utils.validate_arguments, use :meth:Signature.bind and
:func:inspect.signature instead. :issue:1757utils.HTMLBuilder. :issue:1761utils.escape and :func:utils.unescape, use
MarkupSafe instead. :issue:1758python -m werkzeug.serving CLI.
:issue:1834environ["werkzeug.server.shutdown"] function
that is available when running the development server. :issue:1752useragents module and the built-in user agent
parser. Use a dedicated parser library instead by subclassing
user_agent.UserAgent and setting Request.user_agent_class.
:issue:2078posixemulation module. :issue:1759datetime values are timezone-aware with
tzinfo=timezone.utc. This applies to anything using
http.parse_date: Request.date, .if_modified_since,
.if_unmodified_since; Response.date, .expires,
.last_modified, .retry_after; parse_if_range_header, and
IfRange.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:2040Request and Response classes. Using the mixin classes is no
longer necessary and will show a deprecation warning. Checking
isinstance or issubclass against BaseRequest and
BaseResponse will show a deprecation warning and check against
Request or Response instead. :issue:1963Request.json_module and
Response.json_module. :pr:1766Response.get_json() no longer caches the result, and the
cache parameter is removed. :issue:1698Response.freeze() generates an ETag header if one is not
set. The no_etag parameter (which usually wasn't visible
anyway) is no longer used. :issue:1963url_scheme argument to :meth:~routing.MapAdapter.build
to override the bound scheme. :pr:1721build()
won't append an unnecessary ?. Also drop any number of None
items in a list. :issue:1992Headers object to a test client method or
EnvironBuilder, multiple values for a key are joined into one
comma separated value. This matches the HTTP spec on multi-value
headers. :issue:1655Response.status and status_code uses identical
parsing and error checking. :issue:1658, :pr:1728MethodNotAllowed and RequestedRangeNotSatisfiable take a
response kwarg, consistent with other HTTP errors. :pr:1748~exceptions.Unauthorized produces
one WWW-Authenticate header per value in www_authenticate,
rather than joining them into a single value, to improve
interoperability with browsers and other clients. :pr:1755parse_authorization_header can't decode the header value, it
returns None instead of raising a UnicodeDecodeError.
:issue:18161807REQUEST_URI and
RAW_URI. :issue:1781default_stream_factory to match
the order used when calling it. :pr:1085send_file function to generate a response that serves a
file. Adapted from Flask's implementation. :issue:265, :pr:1850send_from_directory function to safely serve an untrusted
path within a trusted directory. Adapted from Flask's
implementation. :issue:1880send_file takes download_name, which is passed even if
as_attachment=False by using Content-Disposition: inline.
download_name replaces Flask's attachment_filename.
:issue:1869send_file sets conditional=True and max_age=None by
default. Cache-Control is set to no-cache if max_age is
not set, otherwise public. This tells browsers to validate
conditional requests instead of using a timed cache.
max_age=None replaces Flask's cache_timeout=43200.
:issue:1882send_file can be called with etag="string" to set a custom
ETag instead of generating one. etag replaces Flask's
add_etags. :issue:1868send_file sets the Content-Encoding header if an encoding is
returned when guessing mimetype from download_name.
:pr:3896generate_password_hash. Increase
PBKDF2 iterations to 260000 from 150000. Increase salt length to 16
from 8. Use secrets module to generate salt. :pr:1935sys.stdin is somehow None.
:pr:1915delete_cookie to match set_cookie and the
attributes modern browsers expect. :pr:1889utils.cookie_date is deprecated, use utils.http_date
instead. The value for Set-Cookie expires is no longer "-"
delimited. :pr:2040request.headers instead of request.environ to look up
header attributes. :pr:1808Client request methods (client.get, etc.) always
return an instance of TestResponse. In addition to the normal
behavior of Response, this class provides request with the
request that produced the response, and history to track
intermediate responses when follow_redirects is used.
:issue:763, 1894Client request methods takes an auth parameter to
add an Authorization header. It can be an Authorization
object or a (username, password) tuple for Basic auth.
:pr:1809response.close() on a response from the test Client
will close the request input stream. This matches file behavior
and can prevent a ResourceWarning in some cases. :issue:1785EnvironBuilder.from_environ decodes values encoded for WSGI, to
avoid double encoding the new values. :pr:1959sys.path entries, which should contain
most user code. It will also watch all Python files under
directories given in extra_files. :pr:1945__pycache__ directories again. :pr:1945run_simple takes exclude_patterns a list of fnmatch
patterns that will not be scanned by the reloader. :issue:13336265
and potentially allowed setting __Secure prefixed cookies.
:pr:196519231967rb+ instead of
wb+ mode for better compatibility with some libraries.
:issue:19611897Cross-Origin-Opener-Policy and
Cross-Origin-Embedder-Policy response header properties.
:pr:2008run_simple tries to show a valid IP address when binding to all
addresses, instead of 0.0.0.0 or ::. It also warns about not
running the development server in production in this case.
:issue:196418321937Request and Response 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:2005multipart/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, 875LocalProxy 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,
including isinstance. Use issubclass(type(obj), LocalProxy)
to check if an object is actually a proxy. :issue:1754Local uses ContextVar on Python 3.7+ instead of
threading.local. :pr:1778request.values does not include form for GET requests (even
though GET bodies are undefined). This prevents bad caching proxies
from caching form data instead of query strings. :pr:2037environ as
werkzeug.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:2052websocket=True mode for WebSocket upgrade
requests. :issue:2052UserAgentParser to handle more cases. :issue:1971werzeug.DechunkedInput.readinto will not read beyond the size of
the buffer. :issue:20212051pbkdf2_hex, pbkdf2_bin, and safe_str_cmp are deprecated.
hashlib and hmac provide equivalents. :pr:2083invalidate_cached_property is deprecated. Use del obj.name
instead. :pr:2084Href is deprecated. Use werkzeug.routing instead.
:pr:2085Request.disable_data_descriptor is deprecated. Create the
request with shallow=True instead. :pr:2085HTTPException.wrap is deprecated. Create a subclass manually
instead. :pr:2085Released 2020-03-31
RequestRedirect.get_response optional.
:issue:171817231731http_date zero fills years < 1000 to always output four digits.
:issue:17391746io.BytesIO to
FileStorage.save. :issue:1733Released 2020-02-06
1478)1477)werkzeug
module in favor of direct imports. For example, instead of
import werkzeug; werkzeug.url_quote, do
from werkzeug.urls import url_quote. Install version 0.16 first
to see deprecation warnings while upgrading. :issue:2, :pr:1640utils.invalidate_cached_property() to invalidate cached
properties. (:pr:1474)Set-Cookie response header are not
ignored when parsing the Cookie request header. This allows
cookies with names such as "expires" and "version". (:issue:1495)MultiDict to capture all
values for cookies with the same key. cookies[key] returns the
first value rather than the last. Use cookies.getlist(key) to
get all values. parse_cookie also defaults to a MultiDict.
:issue:1562, :pr:1458charset=utf-8 to an HTTP exception response's
CONTENT_TYPE header. (:pr:1526)913, :issue:1037,
:pr:153215561572)7601584~exceptions.InternalServerError has a original_exception
attribute that frameworks can use to track the original cause of the
error. :pr:1590X-Foo is the same as x-foo. :pr:1605http.dump_cookie accepts 'None' as a value for
samesite. :issue:1549~test.Client.set_cookie accepts a samesite argument.
:pr:1705Response.content_security_policy data structure. :pr:1617LanguageAccept will fall back to matching "en" for "en-US" or
"en-US" for "en" to better support clients or translations that
only match at the primary language tag. :issue:450, :pr:1507MIMEAccept uses MIME parameters for specificity when matching.
:issue:458, :pr:1574SSLContext
configured to verify client certificates, the certificate in PEM
format will be available as environ["SSL_CLIENT_CERT"].
:pr:1469is_resource_modified will run for methods other than GET and
HEAD, rather than always returning False. :issue:409SharedDataMiddleware returns 404 rather than 500 when trying to
access a directory instead of a file with the package loader. The
dependency on setuptools and pkg_resources is removed.
:issue:1599response.cache_control.immutable flag. Keep in mind that
browser support for this Cache-Control header option is still
experimental and may not be implemented. :issue:118512351555FileStorage.save() supports pathlib and :pep:519
PathLike objects. :issue:16531661host_matching is enabled takes into account
the current host when there are duplicate endpoints with different
hosts. :issue:488429 TooManyRequests and 503 ServiceUnavailable HTTP
exceptions takes a retry_after parameter to set the
Retry-After header. :issue:1657Map and Rule have a merge_slashes option to collapse
multiple slashes into one, similar to how many HTTP servers behave.
This is enabled by default. :pr:1286, 16941678update, setlist, and setlistdefault methods to the
Headers data structure. extend method can take MultiDict
and kwargs. :pr:1687, 1697491Request and Response wrappers. :pr:1699Accept values are no longer ordered alphabetically for equal
quality tags. Instead the initial order is preserved. :issue:1686Map.lock_class attribute for alternative
implementations. :pr:170217097233. This may help serving
media to older browsers. :issue:410, 1704~middleware.shared_data.SharedDataMiddleware default
fallback_mimetype is application/octet-stream. If a filename
looks like a text mimetype, the utf-8 charset is added to it.
This matches the behavior of :class:~wrappers.BaseResponse and
Flask's send_file(). :issue:1689Released 2020-01-27
16631659Released 2019-09-19
Deprecate most top-level attributes provided by the werkzeug
module in favor of direct imports. The deprecated imports will be
removed in version 1.0.
For example, instead of import werkzeug; werkzeug.url_quote, do
from werkzeug.urls import url_quote. A deprecation warning will
show the correct import to use. werkzeug.exceptions and
werkzeug.routing should also be imported instead of accessed,
but for technical reasons can't show a warning.
:issue:2, :pr:1640
Released 2019-09-04
flask run command failing with "No module named
Scripts\flask". :issue:1614ProxyFix trusts the X-Forwarded-Proto header by default.
:issue:1630num_proxies argument to ProxyFix sets
x_for, x_proto, and x_host to match 0.14 behavior. This
is intended to make intermediate upgrades less disruptive, but the
argument will still be removed in 1.0. :issue:1630Released 2019-07-17
TypeError due to changes to ast.Module in Python 3.8.
:issue:15511553~exceptions.BadRequestKeyError adds the KeyError
message to the description if e.show_exception is set to
True. This is a more secure default than the original 0.15.0
behavior and makes it easier to control without losing information.
:pr:1592158116071600sys.executable even if the script is
marked executable, reverting a behavior intended for NixOS
introduced in 0.15. The reloader should no longer cause
OSError: [Errno 8] Exec format error. :issue:1482,
:issue:1580SharedDataMiddleware safely handles paths with Windows drive
names. :issue:1589Released 2019-05-14
SyntaxError on Python 2.7.5. (:issue:1544)Released 2019-05-14
1080)response argument to :exc:~exceptions.Unauthorized.
(:pr:1527)~exceptions.Unauthorized doesn't add the WWW-Authenticate
header if www_authenticate is not given. (:issue:1516)b''. (:issue:1502)~middleware.profiler.ProfilerMiddleware to correctly handle
float values. (:issue:1511)~middleware.lint.LintMiddleware to work on Python 3.
(:issue:1510)1536)Released 2019-04-02
Rule code generation uses a filename that coverage will ignore.
The previous value, "generated", was causing coverage to fail.
(:issue:1487)1491)1498)"werkzeug" logger only adds a handler if there is no handler
configured for its level in the logging chain. This avoids double
logging if other code configures logging first. (:issue:1492)Released 2019-03-21
~exceptions.Unauthorized takes description as the first
argument, restoring previous behavior. The new www_authenticate
argument is listed second. (:issue:1483)Released 2019-03-19
Building URLs is ~7x faster. Each :class:~routing.Rule compiles
an optimized function for building itself. (:pr:1281)
:meth:MapAdapter.build() <routing.MapAdapter.build> can be passed
a :class:~datastructures.MultiDict to represent multiple values
for a key. It already did this when passing a dict with a list
value. (:pr:724)
path_info defaults to '/' for
:meth:Map.bind() <routing.Map.bind>. (:issue:740, :pr:768,
:pr:1316)
Change RequestRedirect code from 301 to 308, preserving the verb
and request body (form data) during redirect. (:pr:1342)
int and float converters in URL rules will handle negative
values if passed the signed=True parameter. For example,
/jump/<int(signed=True):count>. (:pr:1355)
Location autocorrection in :func:Response.get_wsgi_headers() <wrappers.BaseResponse.get_wsgi_headers> is relative to the current
path rather than the root path. (:issue:693, :pr:718,
:pr:1315)
412 responses once again include entity headers and an error message
in the body. They were originally omitted when implementing
If-Match (:pr:1233), but the spec doesn't seem to disallow it.
(:issue:1231, :pr:1255)
The Content-Length header is removed for 1xx and 204 responses. This
fixes a previous change where no body would be sent, but the header
would still be present. The new behavior matches RFC 7230.
(:pr:1294)
:class:~exceptions.Unauthorized takes a www_authenticate
parameter to set the WWW-Authenticate header for the response,
which is technically required for a valid 401 response.
(:issue:772, :pr:795)
Add support for status code 424 :exc:~exceptions.FailedDependency.
(:pr:1358)
:func:http.parse_cookie ignores empty segments rather than
producing a cookie with no key or value. (:issue:1245, :pr:1301)
http.parse_authorization_header (and
:class:~datastructures.Authorization,
:attr:~wrappers.Request.authorization) treats the authorization
header as UTF-8. On Python 2, basic auth username and password are
unicode. (:pr:1325)
:func:~http.parse_options_header understands :rfc:2231 parameter
continuations. (:pr:1417)
:func:~urls.uri_to_iri does not unquote ASCII characters in the
unreserved class, such as space, and leaves invalid bytes quoted
when decoding. :func:~urls.iri_to_uri does not quote reserved
characters. See :rfc:3987 for these character classes.
(:pr:1433)
get_content_type appends a charset for any mimetype that ends
with +xml, not just those that start with application/.
Known text types such as application/javascript are also given
charsets. (:pr:1439)
Clean up werkzeug.security module, remove outdated hashlib
support. (:pr:1282)
In :func:~security.generate_password_hash, PBKDF2 uses 150000
iterations by default, increased from 50000. (:pr:1377)
:class:~wsgi.ClosingIterator calls close on the wrapped
iterable, not the internal iterator. This doesn't affect objects
where __iter__ returned self. For other objects, the method
was not called before. (:issue:1259, :pr:1260)
Bytes may be used as keys in :class:~datastructures.Headers, they
will be decoded as Latin-1 like values are. (:pr:1346)
:class:~datastructures.Range validates that list of range tuples
passed to it would produce a valid Range header. (:pr:1412)
:class:~datastructures.FileStorage looks up attributes on
stream._file if they don't exist on stream, working around
an issue where :func:tempfile.SpooledTemporaryFile didn't
implement all of :class:io.IOBase. See
https://github.com/python/cpython/pull/3249. (:pr:1409)
:class:CombinedMultiDict.copy() <datastructures.CombinedMultiDict>
returns a shallow mutable copy as a
:class:~datastructures.MultiDict. The copy no longer reflects
changes to the combined dicts, but is more generally useful.
(:pr:1420)
The version of jQuery used by the debugger is updated to 3.3.1.
(:pr:1390)
The debugger correctly renders long markupsafe.Markup instances.
(:pr:1393)
The debugger can serve resources when Werkzeug is installed as a
zip file. DebuggedApplication.get_resource uses
pkgutil.get_data. (:pr:1401)
The debugger and server log support Python 3's chained exceptions.
(:pr:1396)
The interactive debugger highlights frames that come from user code
to make them easy to pick out in a long stack trace. Note that if an
env was created with virtualenv instead of venv, the debugger may
incorrectly classify some frames. (:pr:1421)
Clicking the error message at the top of the interactive debugger
will jump down to the bottom of the traceback. (:pr:1422)
When generating a PIN, the debugger will ignore a KeyError
raised when the current UID doesn't have an associated username,
which can happen in Docker. (:issue:1471)
:class:~exceptions.BadRequestKeyError adds the KeyError
message to the description, making it clearer what caused the 400
error. Frameworks like Flask can omit this information in production
by setting e.args = (). (:pr:1395)
If a nested ImportError occurs from :func:~utils.import_string
the traceback mentions the nested import. Removes an untested code
path for handling "modules not yet set up by the parent."
(:pr:735)
Triggering a reload while using a tool such as PDB no longer hides
input. (:pr:1318)
The reloader will not prepend the Python executable to the command
line if the Python file is marked executable. This allows the
reloader to work on NixOS. (:pr:1242)
Fix an issue where sys.path would change between reloads when
running with python -m app. The reloader can detect that a
module was run with "-m" and reconstructs that instead of the file
path in sys.argv when reloading. (:pr:1416)
The dev server can bind to a Unix socket by passing a hostname like
unix://app.socket. (:pr:209, :pr:1019)
Server uses IPPROTO_TCP constant instead of SOL_TCP for
Jython compatibility. (:pr:1375)
When using an adhoc SSL cert with :func:~serving.run_simple, the
cert is shown as self-signed rather than signed by an invalid
authority. (:pr:1430)
The development server logs the unquoted IRI rather than the raw
request line, to make it easier to work with Unicode in request
paths during development. (:issue:1115)
The development server recognizes ConnectionError on Python 3 to
silence client disconnects, and does not silence other OSErrors
that may have been raised inside the application. (:pr:1418)
The environ keys REQUEST_URI and RAW_URI contain the raw
path before it was percent-decoded. This is non-standard, but many
WSGI servers add them. Middleware could replace PATH_INFO with
this to route based on the raw value. (:pr:1419)
:class:~test.EnvironBuilder doesn't set CONTENT_TYPE or
CONTENT_LENGTH in the environ if they aren't set. Previously
these used default values if they weren't set. Now it's possible to
distinguish between empty and unset values. (:pr:1308)
The test client raises a ValueError if a query string argument
would overwrite a query string in the path. (:pr:1338)
:class:test.EnvironBuilder and :class:test.Client take a
json argument instead of manually passing data and
content_type. This is serialized using the
:meth:test.EnvironBuilder.json_dumps method. (:pr:1404)
:class:test.Client redirect handling is rewritten. (:pr:1402)
test.EnvironBuilder sets the content type and length
headers in addition to the WSGI keys when detecting them from
the data.buffered=False to ensure iterator middleware can run cleanup
code safely. Only the last response is not buffered. (:pr:988):class:~test.EnvironBuilder, :class:~datastructures.FileStorage,
and :func:wsgi.get_input_stream no longer share a global
_empty_stream instance. This improves test isolation by
preventing cases where closing the stream in one request would
affect other usages. (:pr:1340)
The default SecureCookie.serialization_method will change from
:mod:pickle to :mod:json in 1.0. To upgrade existing tokens,
override :meth:~contrib.securecookie.SecureCookie.unquote to try
pickle if json fails. (:pr:1413)
CGIRootFix no longer modifies PATH_INFO for very old
versions of Lighttpd. LighttpdCGIRootFix was renamed to
CGIRootFix in 0.9. Both are deprecated and will be removed in
version 1.0. (:pr:1141)
:class:werkzeug.wrappers.json.JSONMixin has been replaced with
Flask's implementation. Check the docs for the full API.
(:pr:1445)
The contrib modules are deprecated and will either be moved into
werkzeug core or removed completely in version 1.0. Some modules
that already issued deprecation warnings have been removed. Be sure
to run or test your code with
python -W default::DeprecationWarning to catch any deprecated
code you're using. (:issue:4)
LintMiddleware has moved to :mod:werkzeug.middleware.lint.ProfilerMiddleware has moved to
:mod:werkzeug.middleware.profiler.ProxyFix has moved to :mod:werkzeug.middleware.proxy_fix.JSONRequestMixin has moved to :mod:werkzeug.wrappers.json.cache has been extracted into a separate project,
cachelib <https://github.com/pallets/cachelib>_. The version
in Werkzeug is deprecated.securecookie and sessions have been extracted into a
separate project,
secure-cookie <https://github.com/pallets/secure-cookie>_. The
version in Werkzeug is deprecated.fixers, except ProxyFix, is deprecated.wrappers, except JSONMixin, is deprecated.atom is deprecated. This did not fit in with the rest of
Werkzeug, and is better served by a dedicated library in the
community.jsrouting is removed. Set URLs when rendering templates
or JSON responses instead.limiter is removed. Its specific use is handled by Werkzeug
directly, but stream limiting is better handled by the WSGI
server in general.testtools is removed. It did not offer significant benefit
over the default test client.iterio is deprecated.:func:wsgi.get_host no longer looks at X-Forwarded-For. Use
:class:~middleware.proxy_fix.ProxyFix to handle that.
(:issue:609, :pr:1303)
:class:~middleware.proxy_fix.ProxyFix is refactored to support
more headers, multiple values, and more secure configuration.
num_proxies argument is deprecated. (:pr:1314)SERVER_NAME and SERVER_PORT based on
X-Forwarded-Host. (:pr:1314)SERVER_PORT and modifies HTTP_HOST based on
X-Forwarded-Port. (:issue:1023, :pr:1304)SCRIPT_NAME based on X-Forwarded-Prefix.
(:issue:1237)werkzeug.proxy_fix.orig key, a dict. The individual keys
werkzeug.proxy_fix.orig_remote_addr,
werkzeug.proxy_fix.orig_wsgi_url_scheme, and
werkzeug.proxy_fix.orig_http_host are deprecated.Middleware from werkzeug.wsgi has moved to separate modules
under werkzeug.middleware, along with the middleware moved from
werkzeug.contrib. The old werkzeug.wsgi imports are
deprecated and will be removed in version 1.0. (:pr:1452)
werkzeug.wsgi.DispatcherMiddleware has moved to
:class:werkzeug.middleware.dispatcher.DispatcherMiddleware.werkzeug.wsgi.ProxyMiddleware as moved to
:class:werkzeug.middleware.http_proxy.ProxyMiddleware.werkzeug.wsgi.SharedDataMiddleware has moved to
:class:werkzeug.middleware.shared_data.SharedDataMiddleware.:class:~middleware.http_proxy.ProxyMiddleware proxies the query
string. (:pr:1252)
The filenames generated by
:class:~middleware.profiler.ProfilerMiddleware can be customized.
(:issue:1283)
The werkzeug.wrappers module has been converted to a package,
and its various classes have been organized into separate modules.
Any previously documented classes, understood to be the existing
public API, are still importable from werkzeug.wrappers, or may
be imported from their specific modules. (:pr:1456)
Released on December 31st 2017
Released on December 31st 2017
Request.application.SpooledTemporaryFile.werkzeug.wsgi.ProxyMiddlewarehas for NullCacheget_multi on cache clients now returns lists all the time.filename* filename attributes according to
RFC 2231EnvironHeaders object now skips over empty content type and
lengths if they are set to falsy values.Client and EnvironBuilder now support mimetypes like
the request object does.EnvironHeaders no longer raises weird errors if non string keys
are passed to it.Released on December 7th 2017
pallets/meta#24)TypeError when port is not an integer. (:pr:1088)werkzeug.script. Use Click_ instead.
(:pr:1090)response.age is parsed as a timedelta. Previously, it was
incorrectly treated as a datetime. The header value is an integer
number of seconds, not a date string. (:pr:414)TypeConversionDict where errors are not propagated
when using the converter. (:issue:1102)Authorization.qop is a string instead of a set, to comply with
RFC 2617. (:pr:984)BaseResponse has a new attribute max_cookie_size and
dump_cookie has a new argument max_size to configure this.
(:pr:780, :pr:1109)werkzeug.contrib.lint.GuardedIterator.close.
(:pr:1116)BaseResponse.calculate_content_length now correctly works for
Unicode responses on Python 3. It first encodes using
iter_encoded. (:issue:705)1205)1197)1208)1198).. _Click: https://palletsprojects.com/p/click/
Released on May 16 2017
#892 prevented Werkzeug from correctly
logging the IP of a remote client behind a reverse proxy, even when using
ProxyFix.safe_join on Windows.Released on March 15th 2017
OSError: [WinError 10038]). See pull request #1081Headers. See #1084.Released on March 10th 2017
inspect.getfullargspec internally when available as
inspect.getargspec is gone in 3.6FileStorage would result in an infinite
loop.collections module in the stdlib. See #794.LocalProxy's wrapped object is a function, refer to it with wrapped
attribute.generate_password_hash have been changed to more secure
ones, see pull request #753.#933.test.Client now properly handles Location headers with relative URLs, see
pull request #879.HTTPException is raised, it now prints the description, for easier
debugging.view-methods under Python 2,
see pull request #968.MultiPartParser when no stream_factory was provided
during initialization, see pull request #973.#994.#907.SharedDataMiddleware with frozen packages, see pull
request #959.Range header parsing function fixed for invalid values #974.#978.#1004.#1013.#1031.#1033.best_match for mime types (for example in
requests.accept_mimetypes.best_match)python -m werkzeug.serving.Released on December 30th 2016.
Released on December 30th 2016.
ForkingMixIn, raise exception
when creating ForkingWSGIServer on such a platform, see PR #999.Released on December 26th 2016.
Released on December 26th 2016.
#1000.EnvironBuilder properties that were previously
unintentionally missing.Released on August 31st 2016.
parse_options_header where an invalid content type
starting with comma or semi-colon would result in an invalid return value,
see issue #995.#979.#1001.Released on May 24th 2016.
Released on April 24th 2016.
Released on April 15th 2016.
Released on April 14th 2016.
Released on April 14th 2016.
Released on March 22nd 2016.
Released on February 14th 2016.
Released on December 20th 2015.
Released on November 12th 2015.
Released on November 10th 2015.
Released on November 8th 2015, codename Gleisbaumaschine.
reloader_paths option to run_simple and other functions in
werkzeug.serving. This allows the user to completely override the Python
module watching of Werkzeug with custom paths.property type (issue #616).bind_to_environ now doesn't differentiate between implicit and explicit
default port numbers in HTTP_HOST (pull request #204).BuildErrors are now more informative. They come with a complete sentence
as error message, and also provide suggestions (pull request #691).#703).#702).mimetype parameters on request and response classes are now always
converted to lowercase.#550)UTF-8 as filesystem encoding on Unix if Python
detected it as ASCII.has method on caches.parse_options_header (pull request #643).(bugfix release, release date yet to be decided)
#722).werkzeug.datastructures.ETags under Python 3 (issue
#744).(bugfix release, released on March 26th 2015)
(bugfix release, released on March 26th 2015)
(bugfix release, released on March 26th 2015)
empty could break third-party libraries that relied on
keyword arguments (pull request #675)Rule.empty by providing a ```get_empty_kwargsto allow setting custom kwargs without having to override entireemptymethod. (pull request#675``)extra_files parameter for reloader to not cause startup
to crash when included in server paramsMultiDict when building URLs is now not supported again. The behavior
introduced several regressions.#715).(bugfix release, released on February 3rd 2015)
#667).#663).Released on January 30th 2015, codename Bagger.
contrib.cache.sys.maxint
not being defined.~werkzeug.serving.make_ssl_devcert to fail with an exception.len for
:class:werkzeug.datastructures.CombinedMultiDict to crash.py.test.#496 and
#571).ssl module instead of OpenSSL for the builtin server
(issue #434). This means that OpenSSL contexts are not supported anymore,
but instead ssl.SSLContext from the stdlib.#254).cache.RedisCache now supports arbitrary **kwargs for the redis
object.werkzeug.test.Client now uses the original request method when resolving
307 redirects (pull request #556).werkzeug.datastructures.MIMEAccept now properly deals with mimetype
parameters (pull request #205).werkzeug.datastructures.Accept now handles a quality of 0 as
intolerable, as per RFC 2616 (pull request #536).werkzeug.urls.url_fix now properly encodes hostnames with idna
encoding (issue #559). It also doesn't crash on malformed URLs anymore
(issue #582).werkzeug.routing.MapAdapter.match now recognizes the difference between
the path / and an empty one (issue #360).#469).#611).Response subclass to use when calling
:func:~werkzeug.utils.redirect\ .werkzeug.test.EnvironBuilder now doesn't use the request method anymore
to guess the content type, and purely relies on the form, files and
input_stream properties (issue #620).Content-Length when writing to response.stream (issue #451)wrappers.Request.method is now always uppercase, eliminating
inconsistencies of the WSGI environment (issue 647).routing.Rule.empty now works correctly with subclasses of Rule (pull
request #645).#658).(bugfix release, release date to be decided)
werkzeug.debug.tbtools.werkzeug.posixemulation.ImmutableList (issue #492).FileSystemCache atomic (issue
#468).#539).werkzeug.debug.tbtools.Frame objects (issues
#547 and #532).AttributeError masking in werkzeug.utils.import_string (issue
#182).#519).werkzeug.contrib.cache.MemcachedCache (issue #533).werkzeug.exceptions.abort would raise an arbitrary subclass
of the expected class (issue #422).jsrouting (due to removal of werkzeug.templates)werkzeug.urls.url_fix now doesn't crash on malformed URLs anymore, but
returns them unmodified. This is a cheap workaround for #582, the proper
fix is included in version 0.10.werkzeug.wrappers.Request doesn't crash on non-ASCII-values
anymore (pull request #466).cache.RedisCache when combined with redis.StrictRedis
object (pull request #583).qop parameter for WWW-Authenticate headers is now always quoted,
as required by RFC 2617 (issue #633).werkzeug.contrib.cache.SimpleCache with Python 3 where add/set
may throw an exception when pruning old entries from the cache (pull request
#651).(bugfix release, released on June 7th 2014)
itms-service.(bugfix release, released on June 7th 2014)
os.urandom().(bugfix release, released on August 26th 2013)
(bugfix release, released on July 25th 2013)
Restored behavior of the data descriptor of the request class to pre 0.9
behavior. This now also means that .data and .get_data() have
different behavior. New code should use .get_data() always.
In addition to that there is now a flag for the .get_data() method that
controls what should happen with form data parsing and the form parser will
honor cached data. This makes dealing with custom form data more consistent.
(bugfix release, released on July 18th 2013)
unsafe parameter to urls.url_quote.urls.url_quote_plus not quoting
'+' correctly.~werkzeug.contrib.RedisCache to
Python 3.3.~werkzeug.contrib.MemcachedCache to
Python 3.3~werkzeug.local.release_local.AttributeError that sometimes occurred when accessing the
:attr:werkzeug.wrappers.BaseResponse.is_streamed attribute.(bugfix release, released on June 14th 2013)
url_quote not producing the right escape
codes for single digit codepoints.~werkzeug.wsgi.SharedDataMiddleware not
reading the path correctly and breaking on etag generation in some
cases.Expect: 100-continue in the development server
to resolve issues with curl.Released on June 13nd 2013, codename Planierraupe.
~werkzeug.wsgi.LimitedStream.tell
on the limited stream.~werkzeug.datastructures.ETags now is nonzero if it
contains at least one etag of any kind, including weak ones.wsgi.make_chunk_iter and make_line_iter now support processing
of iterators and streams.+.werkzeug.security.generate_password_hash and
check functions now support any of the hashlib algorithms.wsgi.get_current_url is now ascii safe for browsers sending
non-ascii data in query strings.werkzeug.http.parse_options_headerwerkzeug.http.parse_dict_header.LighttpdCGIRootFix to CGIRootFix.+ as safe when fixing URLs as people love misusing them.fix_headers.header_list.iter_encoded.writable parameter on
the cached property.wsgi.get_query_string, wsgi.get_path_info and
wsgi.get_script_name and made the wsgi.pop_path_info and
wsgi.peek_path_info functions perform unicode decoding. This
was necessary to avoid having to expose the WSGI encoding dance
on Python 3.content_encoding and content_md5 to the request object's
common request descriptor mixin.options and trace to the test client.werkzeug.wrappers.BaseResponse in a with
statement.get_app_iter to fetch the response early so that it does not
fail when wrapping a response iterable. This makes filtering easier.get_data and set_data methods for responses.get_data for requests.data descriptors for request and response objects.as_bytes operations to some of the headers to simplify working
with things like cookies.(bugfix release, release date to be announced)
(bugfix release, released on February 5th 2012)
wsgi.make_line_iter
where lines longer than the buffer size were not handled
properly.(bugfix release, released on December 16th 2011)
__doc__.(bugfix release, released on September 30th 2011)
copy.copy.Released on September 29th 2011, codename Lötkolben
~werkzeug.exceptions.BadRequestKeyError.werkzeug.wrappers.BaseRequest._load_form_data.query_args parameter since we're only
passing them through for redirects.~werkzeug.wrappers.BaseResponse.data attribute is set
for efficiency and simplicity reasons.autocorrect_location_header and
automatically_set_content_length on the response objects.wsgi.make_line_iter now requires a limit that is
not higher than the length the stream can provide.(bugfix release, released on September 30th 2011)
(bugfix release, released on July 26th 2011)
Released on July 24th 2011, codename Schraubschlüssel
url_decode and :func:url_encode performance.werkzeug.import_string now works with partially set up
packages properly.ValueErrors being raised on calls to best_match on
MIMEAccept objects when invalid user data was supplied.werkzeug.contrib.kickstart and werkzeug.contrib.testtoolscall_on_close now can be used as a decorator.BaseRequest.scheme.is_behind_proxy. Use a WSGI middleware
instead that rewrites the REMOTE_ADDR according to your setup.
Also see the :class:werkzeug.contrib.fixers.ProxyFix for
a drop-in replacement.werkzeug.security.safe_join.accept_json property analogous to accept_html on the
:class:werkzeug.datastructures.MIMEAccept.werkzeug.utils.import_string now fails with much better
error messages that pinpoint to the problem.If-Range header
(:func:werkzeug.http.parse_if_range_header and
:class:werkzeug.datastructures.IfRange).Range header
(:func:werkzeug.http.parse_range_header and
:class:werkzeug.datastructures.Range).Content-Range header of responses
and provided an accessor object for it
(:func:werkzeug.http.parse_content_range_header and
:class:werkzeug.datastructures.ContentRange).(bugfix release, released on April 23th 2010)
implicit_seqence_conversion attribute of the
request object to implicit_sequence_conversion.(bugfix release, released on April 13th 2010)
NameError in the session system.logging.basicConfig (#499)HEAD is now implicitly added as method in the routing system if
GET is present. Not doing that was considered a bug because often
code assumed that this is the case and in web servers that do not
normalize HEAD to GET this could break HEAD requests.Released on Feb 19th 2010, codename Hammer.
FileStorage now gives access to the multipart headers.cached_property.writeable has been deprecated.MapAdapter.match now accepts a return_rule keyword argument
that returns the matched Rule instead of just the endpointrouting.Map.bind_to_environ raises a more correct error message
now if the map was bound to an invalid WSGI environment.fix_headers
function is still called in case it was overridden.
You should however change your application to use get_wsgi_headers if
you need header modifications before responses are sent as the backwards
compatibility support will go away in future versions.append_slash_redirect no longer requires the QUERY_STRING to be
in the WSGI environment.~werkzeug.contrib.wrappers.DynamicCharsetResponseMixin~werkzeug.contrib.wrappers.DynamicCharsetRequestMixinBaseRequest.url_charset__repr__ now.make_line_iter and the multipart parser
for binary uploads.~werkzeug.BaseResponse.is_streamedEnvironBuilder that caused PATH_INFO and
SCRIPT_NAME to end up in the environ unquoted.werkzeug.BaseResponse.freeze now sets the content length.werkzeug.MIMEAccept.best_matchwerkzeug.LimitedStream.werkzeug.extract_path_infourl_fixfallback_mimetype to :class:werkzeug.SharedDataMiddleware.BaseResponse.iter_encoded's charset parameter.BaseResponse.make_sequence,
:attr:BaseResponse.is_sequence and
:meth:BaseResponse._ensure_sequence.werkzeug.Mapimport_string accepts unicode strings as well now.__repr__ and __str__ of
:exc:werkzeug.exceptions.HTTPExceptionwerkzeug.routing.Map now has a class attribute with
the default converter mapping. This helps subclasses to override
the converters without passing them to the constructor.OrderedMultiDict(bugfix release for 0.5, released on July 9th 2009)
FileStorageBaseRequest._form_parsing_failed.ImmutableDict.copy, :meth:ImmutableMultiDict.copy and
:meth:ImmutableTypeConversionDict.copy return mutable shallow
copies.make_runserver script action.MultiDict.items and :meth:MutiDict.iteritems now accept an
argument to return a pair for each value of each key.SharedDataMiddleware.Released on April 24th, codename Schlagbohrer.
~contrib.IterIOMIMEAccept and :class:CharsetAccept that work like the
regular :class:Accept but have extra special normalization for mimetypes
and charsets and extra convenience methods.Client now supports cookies.~werkzeug.contrib.fixers module with various
fixes for webserver bugs and hosting setup side-effects.werkzeug.contrib.wrappersis_hop_by_hop_headeris_entity_headerremove_hop_by_hop_headerspop_path_infopeek_path_infowrap_file and :class:FileWrapperLimitedStream from the contrib package into the regular
werkzeug one and changed the default behavior to raise exceptions
rather than stopping without warning. The old class will stick in
the module until 0.6.dump_options_header and :func:parse_options_headerquote_header_value and :func:unquote_header_valueurl_encode and :func:url_decode now accept a separator
argument to switch between & and ; as pair separator. The magic
switch is no longer in place.BaseRequest
object have parameters (or attributes) to limit the number of
incoming bytes (either totally or per field).LanguageAcceptwerkzeug.test.File
was replaced by :class:werkzeug.FileStorage.EnvironBuilder was added and unifies the previous distinct
:func:create_environ, :class:Client and
:meth:BaseRequest.from_values. They all work the same now which
is less confusing.FileStorage.__len__ which previously made the object
falsy for browsers not sending the content length which all browsers
do.SharedDataMiddleware uses wrap_file now and has a
configurable cache timeout.CommonRequestDescriptorsMixinCommonResponseDescriptorsMixin.mimetype_paramswerkzeug.contrib.lintpassthrough_errors to run_simple.secure_filenamemake_line_iterMultiDict copies now instead of revealing internal
lists to the caller for getlist and iteration functions that
return lists.follow_redirect to the :func:open of :class:Client.extra_files in
:func:~werkzeug.script.make_runserver(Bugfix release, released on January 11th 2009)
werkzeug.contrib.cache.Memcached accepts now objects that
implement the memcache.Client interface as alternative to a list of
strings with server addresses.
There is also now a GAEMemcachedCache that connects to the Google
appengine cache.url_encode and all interfaces that call it, support ordering of
options now which however is disabled by default.werkzeug.test that broke File.Map.bind_to_environ uses the Host header now if available.BaseCache.get_dict (#345)werkzeug.test.Client can now run the application buffered in which
case the application is properly closed automatically.Headers.set (#354). Caused header duplication before.Headers.pop (#349). default parameter was not properly
handled.create_environ (#351)Headers is more compatible with wsgiref now.Template.render accepts multidicts now.Released on November 23rd 2008, codename Schraubenzieher.
Client supports an empty data argument now.Response.application that made it impossible to use it
as method decorator.CacheControl.no_cache and CacheControl.private behavior changed to
reflect the possibilities of the HTTP RFC. Setting these attributes to
None or True now sets the value to "the empty value".
More details in the documentation.werkzeug.contrib.atom.AtomFeed.__call__. (#338)BaseResponse.make_conditional now always returns self. Previously
it didn't for post requests and such.html and xhtml.Headers (slicing and indexing
works now)__setitem__ method of Headers that didn't
properly remove all keys on replacing.remove_entity_headers which removes all entity headers from
a list of headers (or a Headers object)remove_entity_headers if the
status code is 304.Href query parameter handling. Previously the last
item of a call to Href was not handled properly if it was a dict.pop operation to better work with environ
properties.(bugfix release, released on June 24th 2008)
werkzeug.contrib.SecureCookie.Released on June 14th 2008, codename EUR325CAT6.
Authorization and AuthorizationMixinWWWAuthenticate and WWWAuthenticateMixinparse_list_headerparse_dict_headerparse_authorization_headerparse_www_authenticate_header_get_current_object method to LocalProxy objectsparse_form_dataMultiDict, CombinedMultiDict, Headers, and EnvironHeaders raise
special key errors now that are subclasses of BadRequest so if you
don't catch them they give meaningful HTTP responses.HTTPUnicodeError which (if not caught) behaves like a BadRequest.BadRequest.wrap.is_xhr on the request objects.dispatch method. (#318)SharedDataMiddleware.Accept.values.EnvironHeaders contain content-type and content-length nowurl_encode treats lists and tuples in dicts passed to it as multiple
values for the same key so that one doesn't have to pass a MultiDict
to the function.validate_argumentsBaseRequest.applicationrun_simple accepts use_debugger and use_evalex parameters now,
like the make_runserver factory function from the script module.environ_property is now read-only by defaultReleased Feb 14th 2008, codename Faustkeil.
AnyConverter to the routing system.werkzeug.contrib.securecookieget_response() method that return a response objectBaseReporterStream is now part of the werkzeug contrib module. From
Werkzeug 0.3 onwards you will have to import it from there.DispatcherMiddleware.RequestRedirect is now a subclass of HTTPException and uses a
301 status code instead of 302.url_encode and url_decode can optionally treat keys as unicode strings
now, too.werkzeug.script has a different caller format for boolean arguments now.lazy_property to cached_property.import_string.empty() method to routing rules.werkzeug.contrib.profiler.extends to Headers.dump_cookie and parse_cookie.as_tuple to the Client.werkzeug.contrib.testtools.werkzeug.unescapeBaseResponse.freezewerkzeug.contrib.atomdescription now which overrides the
default description.MapAdapter has a default for path info now. If you use
bind_to_environ you don't have to pass the path later.Href.find_modulesMethodNotAllowed now if it matches a
rule but for a different method.Released on Dec 9th 2007, codename Wictorinoxger.