diff MoinMoin/support/werkzeug/exceptions.py @ 6094:9f12f41504fc

upgrade werkzeug from 0.8.3 to 0.11.11 no other changes, does not work like this, see next commit.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Mon, 05 Sep 2016 23:25:59 +0200
parents 8de563c487be
children 7f12cf241d5e
line wrap: on
line diff
--- a/MoinMoin/support/werkzeug/exceptions.py	Fri Jan 09 20:17:10 2015 +0100
+++ b/MoinMoin/support/werkzeug/exceptions.py	Mon Sep 05 23:25:59 2016 +0200
@@ -24,7 +24,7 @@
             request = BaseRequest(environ)
             try:
                 return view(request)
-            except HTTPException, e:
+            except HTTPException as e:
                 return e
 
 
@@ -54,14 +54,26 @@
                 return e
 
 
-    :copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
+    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
     :license: BSD, see LICENSE for more details.
 """
 import sys
-from werkzeug._internal import HTTP_STATUS_CODES, _get_environ
+
+# Because of bootstrapping reasons we need to manually patch ourselves
+# onto our parent module.
+import werkzeug
+werkzeug.exceptions = sys.modules[__name__]
+
+from werkzeug._internal import _get_environ
+from werkzeug._compat import iteritems, integer_types, text_type, \
+    implements_to_string
+
+from werkzeug.wrappers import Response
 
 
+@implements_to_string
 class HTTPException(Exception):
+
     """
     Baseclass for all HTTP exceptions.  This exception can be called as WSGI
     application to render a default error page or you can catch the subclasses
@@ -71,10 +83,11 @@
     code = None
     description = None
 
-    def __init__(self, description=None):
-        Exception.__init__(self, '%d %s' % (self.code, self.name))
+    def __init__(self, description=None, response=None):
+        Exception.__init__(self)
         if description is not None:
             self.description = description
+        self.response = response
 
     @classmethod
     def wrap(cls, exception, name=None):
@@ -82,8 +95,9 @@
         also is a subclass of `BadRequest`.
         """
         class newcls(cls, exception):
-            def __init__(self, arg=None, description=None):
-                cls.__init__(self, description)
+
+            def __init__(self, arg=None, *args, **kwargs):
+                cls.__init__(self, *args, **kwargs)
                 exception.__init__(self, arg)
         newcls.__module__ = sys._getframe(1).f_globals.get('__name__')
         newcls.__name__ = name or cls.__name__ + exception.__name__
@@ -92,44 +106,44 @@
     @property
     def name(self):
         """The status name."""
-        return HTTP_STATUS_CODES[self.code]
-
-    def get_description(self, environ):
-        """Get the description."""
-        environ = _get_environ(environ)
-        return self.description
+        return HTTP_STATUS_CODES.get(self.code, 'Unknown Error')
 
-    def get_body(self, environ):
+    def get_description(self, environ=None):
+        """Get the description."""
+        return u'<p>%s</p>' % escape(self.description)
+
+    def get_body(self, environ=None):
         """Get the HTML body."""
-        return (
-            '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
-            '<title>%(code)s %(name)s</title>\n'
-            '<h1>%(name)s</h1>\n'
-            '%(description)s\n'
+        return text_type((
+            u'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
+            u'<title>%(code)s %(name)s</title>\n'
+            u'<h1>%(name)s</h1>\n'
+            u'%(description)s\n'
         ) % {
             'code':         self.code,
             'name':         escape(self.name),
             'description':  self.get_description(environ)
-        }
+        })
 
-    def get_headers(self, environ):
+    def get_headers(self, environ=None):
         """Get a list of headers."""
         return [('Content-Type', 'text/html')]
 
-    def get_response(self, environ):
-        """Get a response object.
+    def get_response(self, environ=None):
+        """Get a response object.  If one was passed to the exception
+        it's returned directly.
 
-        :param environ: the environ for the request.
-        :return: a :class:`BaseResponse` object or a subclass thereof.
+        :param environ: the optional environ for the request.  This
+                        can be used to modify the response depending
+                        on how the request looked like.
+        :return: a :class:`Response` object or a subclass thereof.
         """
-        # lazily imported for various reasons.  For one, we can use the exceptions
-        # with custom responses (testing exception instances against types) and
-        # so we don't ever have to import the wrappers, but also because there
-        # are circular dependencies when bootstrapping the module.
-        environ = _get_environ(environ)
-        from werkzeug.wrappers import BaseResponse
+        if self.response is not None:
+            return self.response
+        if environ is not None:
+            environ = _get_environ(environ)
         headers = self.get_headers(environ)
-        return BaseResponse(self.get_body(environ), self.code, headers)
+        return Response(self.get_body(environ), self.code, headers)
 
     def __call__(self, environ, start_response):
         """Call the exception as WSGI application.
@@ -142,31 +156,14 @@
         return response(environ, start_response)
 
     def __str__(self):
-        return unicode(self).encode('utf-8')
-
-    def __unicode__(self):
-        if 'description' in self.__dict__:
-            txt = self.description
-        else:
-            txt = self.name
-        return '%d: %s' % (self.code, txt)
+        return '%d: %s' % (self.code, self.name)
 
     def __repr__(self):
         return '<%s \'%s\'>' % (self.__class__.__name__, self)
 
 
-class _ProxyException(HTTPException):
-    """An HTTP exception that expands renders a WSGI application on error."""
+class BadRequest(HTTPException):
 
-    def __init__(self, response):
-        Exception.__init__(self, 'proxy exception for %r' % response)
-        self.response = response
-
-    def get_response(self, environ):
-        return self.response
-
-
-class BadRequest(HTTPException):
     """*400* `Bad Request`
 
     Raise if the browser sends something to the application the application
@@ -174,12 +171,13 @@
     """
     code = 400
     description = (
-        '<p>The browser (or proxy) sent a request that this server could '
-        'not understand.</p>'
+        'The browser (or proxy) sent a request that this server could '
+        'not understand.'
     )
 
 
 class ClientDisconnected(BadRequest):
+
     """Internal exception that is raised if Werkzeug detects a disconnected
     client.  Since the client is already gone at that point attempting to
     send the error message to the client might not work and might ultimately
@@ -187,14 +185,32 @@
     it is silenced by default as far as Werkzeug is concerned.
 
     Since disconnections cannot be reliably detected and are unspecified
-    by WSGI to a large extend this might or might not be raised if a client
+    by WSGI to a large extent this might or might not be raised if a client
     is gone.
 
     .. versionadded:: 0.8
     """
 
 
+class SecurityError(BadRequest):
+
+    """Raised if something triggers a security error.  This is otherwise
+    exactly like a bad request error.
+
+    .. versionadded:: 0.9
+    """
+
+
+class BadHost(BadRequest):
+
+    """Raised if the submitted host is badly formatted.
+
+    .. versionadded:: 0.11.2
+    """
+
+
 class Unauthorized(HTTPException):
+
     """*401* `Unauthorized`
 
     Raise if the user is not authorized.  Also used if you want to use HTTP
@@ -202,16 +218,15 @@
     """
     code = 401
     description = (
-        '<p>The server could not verify that you are authorized to access '
+        'The server could not verify that you are authorized to access '
         'the URL requested.  You either supplied the wrong credentials (e.g. '
         'a bad password), or your browser doesn\'t understand how to supply '
-        'the credentials required.</p><p>In case you are allowed to request '
-        'the document, please check your user-id and password and try '
-        'again.</p>'
+        'the credentials required.'
     )
 
 
 class Forbidden(HTTPException):
+
     """*403* `Forbidden`
 
     Raise if the user doesn't have the permission for the requested resource
@@ -219,25 +234,27 @@
     """
     code = 403
     description = (
-        '<p>You don\'t have the permission to access the requested resource. '
-        'It is either read-protected or not readable by the server.</p>'
+        'You don\'t have the permission to access the requested resource. '
+        'It is either read-protected or not readable by the server.'
     )
 
 
 class NotFound(HTTPException):
+
     """*404* `Not Found`
 
     Raise if a resource does not exist and never existed.
     """
     code = 404
     description = (
-        '<p>The requested URL was not found on the server.</p>'
-        '<p>If you entered the URL manually please check your spelling and '
-        'try again.</p>'
+        'The requested URL was not found on the server.  '
+        'If you entered the URL manually please check your spelling and '
+        'try again.'
     )
 
 
 class MethodNotAllowed(HTTPException):
+
     """*405* `Method Not Allowed`
 
     Raise if the server used a method the resource does not handle.  For
@@ -248,6 +265,7 @@
     methods in the header which you can do with that list.
     """
     code = 405
+    description = 'The method is not allowed for the requested URL.'
 
     def __init__(self, valid_methods=None, description=None):
         """Takes an optional list of valid http methods
@@ -261,12 +279,9 @@
             headers.append(('Allow', ', '.join(self.valid_methods)))
         return headers
 
-    def get_description(self, environ):
-        m = escape(environ.get('REQUEST_METHOD', 'GET'))
-        return '<p>The method %s is not allowed for the requested URL.</p>' % m
-
 
 class NotAcceptable(HTTPException):
+
     """*406* `Not Acceptable`
 
     Raise if the server can't return any content conforming to the
@@ -275,26 +290,28 @@
     code = 406
 
     description = (
-        '<p>The resource identified by the request is only capable of '
+        'The resource identified by the request is only capable of '
         'generating response entities which have content characteristics '
         'not acceptable according to the accept headers sent in the '
-        'request.</p>'
-        )
+        'request.'
+    )
 
 
 class RequestTimeout(HTTPException):
+
     """*408* `Request Timeout`
 
     Raise to signalize a timeout.
     """
     code = 408
     description = (
-        '<p>The server closed the network connection because the browser '
-        'didn\'t finish the request within the specified time.</p>'
+        'The server closed the network connection because the browser '
+        'didn\'t finish the request within the specified time.'
     )
 
 
 class Conflict(HTTPException):
+
     """*409* `Conflict`
 
     Raise to signal that a request cannot be completed because it conflicts
@@ -304,25 +321,27 @@
     """
     code = 409
     description = (
-        '<p>A conflict happened while processing the request.  The resource '
+        'A conflict happened while processing the request.  The resource '
         'might have been modified while the request was being processed.'
     )
 
 
 class Gone(HTTPException):
+
     """*410* `Gone`
 
     Raise if a resource existed previously and went away without new location.
     """
     code = 410
     description = (
-        '<p>The requested URL is no longer available on this server and '
-        'there is no forwarding address.</p><p>If you followed a link '
-        'from a foreign page, please contact the author of this page.'
+        'The requested URL is no longer available on this server and there '
+        'is no forwarding address. If you followed a link from a foreign '
+        'page, please contact the author of this page.'
     )
 
 
 class LengthRequired(HTTPException):
+
     """*411* `Length Required`
 
     Raise if the browser submitted data but no ``Content-Length`` header which
@@ -330,12 +349,13 @@
     """
     code = 411
     description = (
-        '<p>A request with this method requires a valid <code>Content-'
-        'Length</code> header.</p>'
+        'A request with this method requires a valid <code>Content-'
+        'Length</code> header.'
     )
 
 
 class PreconditionFailed(HTTPException):
+
     """*412* `Precondition Failed`
 
     Status code used in combination with ``If-Match``, ``If-None-Match``, or
@@ -343,12 +363,13 @@
     """
     code = 412
     description = (
-        '<p>The precondition on the request for the URL failed positive '
-        'evaluation.</p>'
+        'The precondition on the request for the URL failed positive '
+        'evaluation.'
     )
 
 
 class RequestEntityTooLarge(HTTPException):
+
     """*413* `Request Entity Too Large`
 
     The status code one should return if the data submitted exceeded a given
@@ -356,23 +377,25 @@
     """
     code = 413
     description = (
-        '<p>The data value transmitted exceeds the capacity limit.</p>'
+        'The data value transmitted exceeds the capacity limit.'
     )
 
 
 class RequestURITooLarge(HTTPException):
+
     """*414* `Request URI Too Large`
 
     Like *413* but for too long URLs.
     """
     code = 414
     description = (
-        '<p>The length of the requested URL exceeds the capacity limit '
-        'for this server.  The request cannot be processed.</p>'
+        'The length of the requested URL exceeds the capacity limit '
+        'for this server.  The request cannot be processed.'
     )
 
 
 class UnsupportedMediaType(HTTPException):
+
     """*415* `Unsupported Media Type`
 
     The status code returned if the server is unable to handle the media type
@@ -380,12 +403,13 @@
     """
     code = 415
     description = (
-        '<p>The server does not support the media type transmitted in '
-        'the request.</p>'
+        'The server does not support the media type transmitted in '
+        'the request.'
     )
 
 
 class RequestedRangeNotSatisfiable(HTTPException):
+
     """*416* `Requested Range Not Satisfiable`
 
     The client asked for a part of the file that lies beyond the end
@@ -395,11 +419,12 @@
     """
     code = 416
     description = (
-        '<p>The server cannot provide the requested range.'
+        'The server cannot provide the requested range.'
     )
 
 
 class ExpectationFailed(HTTPException):
+
     """*417* `Expectation Failed`
 
     The server cannot meet the requirements of the Expect request-header.
@@ -408,11 +433,12 @@
     """
     code = 417
     description = (
-        '<p>The server could not meet the requirements of the Expect header'
+        'The server could not meet the requirements of the Expect header'
     )
 
 
 class ImATeapot(HTTPException):
+
     """*418* `I'm a teapot`
 
     The server should return this if it is a teapot and someone attempted
@@ -422,11 +448,75 @@
     """
     code = 418
     description = (
-        '<p>This server is a teapot, not a coffee machine'
+        'This server is a teapot, not a coffee machine'
+    )
+
+
+class UnprocessableEntity(HTTPException):
+
+    """*422* `Unprocessable Entity`
+
+    Used if the request is well formed, but the instructions are otherwise
+    incorrect.
+    """
+    code = 422
+    description = (
+        'The request was well-formed but was unable to be followed '
+        'due to semantic errors.'
+    )
+
+
+class PreconditionRequired(HTTPException):
+
+    """*428* `Precondition Required`
+
+    The server requires this request to be conditional, typically to prevent
+    the lost update problem, which is a race condition between two or more
+    clients attempting to update a resource through PUT or DELETE. By requiring
+    each client to include a conditional header ("If-Match" or "If-Unmodified-
+    Since") with the proper value retained from a recent GET request, the
+    server ensures that each client has at least seen the previous revision of
+    the resource.
+    """
+    code = 428
+    description = (
+        'This request is required to be conditional; try using "If-Match" '
+        'or "If-Unmodified-Since".'
+    )
+
+
+class TooManyRequests(HTTPException):
+
+    """*429* `Too Many Requests`
+
+    The server is limiting the rate at which this user receives responses, and
+    this request exceeds that rate. (The server may use any convenient method
+    to identify users and their request rates). The server may include a
+    "Retry-After" header to indicate how long the user should wait before
+    retrying.
+    """
+    code = 429
+    description = (
+        'This user has exceeded an allotted request count. Try again later.'
+    )
+
+
+class RequestHeaderFieldsTooLarge(HTTPException):
+
+    """*431* `Request Header Fields Too Large`
+
+    The server refuses to process the request because the header fields are too
+    large. One or more individual fields may be too large, or the set of all
+    headers is too large.
+    """
+    code = 431
+    description = (
+        'One or more header fields exceeds the maximum size.'
     )
 
 
 class InternalServerError(HTTPException):
+
     """*500* `Internal Server Error`
 
     Raise if an internal server error occurred.  This is a good fallback if an
@@ -434,13 +524,14 @@
     """
     code = 500
     description = (
-        '<p>The server encountered an internal error and was unable to '
+        'The server encountered an internal error and was unable to '
         'complete your request.  Either the server is overloaded or there '
-        'is an error in the application.</p>'
+        'is an error in the application.'
     )
 
 
 class NotImplemented(HTTPException):
+
     """*501* `Not Implemented`
 
     Raise if the application does not support the action requested by the
@@ -448,12 +539,13 @@
     """
     code = 501
     description = (
-        '<p>The server does not support the action requested by the '
-        'browser.</p>'
+        'The server does not support the action requested by the '
+        'browser.'
     )
 
 
 class BadGateway(HTTPException):
+
     """*502* `Bad Gateway`
 
     If you do proxying in your application you should return this status code
@@ -462,45 +554,74 @@
     """
     code = 502
     description = (
-        '<p>The proxy server received an invalid response from an upstream '
-        'server.</p>'
+        'The proxy server received an invalid response from an upstream '
+        'server.'
     )
 
 
 class ServiceUnavailable(HTTPException):
+
     """*503* `Service Unavailable`
 
     Status code you should return if a service is temporarily unavailable.
     """
     code = 503
     description = (
-        '<p>The server is temporarily unable to service your request due to '
+        'The server is temporarily unable to service your request due to '
         'maintenance downtime or capacity problems.  Please try again '
-        'later.</p>'
+        'later.'
+    )
+
+
+class GatewayTimeout(HTTPException):
+
+    """*504* `Gateway Timeout`
+
+    Status code you should return if a connection to an upstream server
+    times out.
+    """
+    code = 504
+    description = (
+        'The connection to an upstream server timed out.'
+    )
+
+
+class HTTPVersionNotSupported(HTTPException):
+
+    """*505* `HTTP Version Not Supported`
+
+    The server does not support the HTTP protocol version used in the request.
+    """
+    code = 505
+    description = (
+        'The server does not support the HTTP protocol version used in the '
+        'request.'
     )
 
 
 default_exceptions = {}
 __all__ = ['HTTPException']
 
+
 def _find_exceptions():
-    for name, obj in globals().iteritems():
+    for name, obj in iteritems(globals()):
         try:
-            if getattr(obj, 'code', None) is not None:
-                default_exceptions[obj.code] = obj
-                __all__.append(obj.__name__)
-        except TypeError: # pragma: no cover
+            is_http_exception = issubclass(obj, HTTPException)
+        except TypeError:
+            is_http_exception = False
+        if not is_http_exception or obj.code is None:
             continue
+        __all__.append(obj.__name__)
+        old_obj = default_exceptions.get(obj.code, None)
+        if old_obj is not None and issubclass(obj, old_obj):
+            continue
+        default_exceptions[obj.code] = obj
 _find_exceptions()
 del _find_exceptions
 
 
-#: raised by the request functions if they were unable to decode the
-#: incoming data properly.
-HTTPUnicodeError = BadRequest.wrap(UnicodeError, 'HTTPUnicodeError')
+class Aborter(object):
 
-
-class Aborter(object):
     """
     When passed a dict of code -> exception items it can be used as
     callable that raises exceptions.  If the first argument to the
@@ -518,8 +639,8 @@
             self.mapping.update(extra)
 
     def __call__(self, code, *args, **kwargs):
-        if not args and not kwargs and not isinstance(code, (int, long)):
-            raise _ProxyException(code)
+        if not args and not kwargs and not isinstance(code, integer_types):
+            raise HTTPException(response=code)
         if code not in self.mapping:
             raise LookupError('no exception for %r' % code)
         raise self.mapping[code](*args, **kwargs)
@@ -534,3 +655,4 @@
 
 # imported here because of circular dependencies of werkzeug.utils
 from werkzeug.utils import escape
+from werkzeug.http import HTTP_STATUS_CODES