Hello community, here is the log from the commit of package python-waitress for openSUSE:Factory checked in at 2013-08-15 12:30:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-waitress (Old) and /work/SRC/openSUSE:Factory/.python-waitress.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-waitress" Changes: -------- --- /work/SRC/openSUSE:Factory/python-waitress/python-waitress.changes 2013-06-29 14:36:45.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-waitress.new/python-waitress.changes 2013-08-15 12:30:23.000000000 +0200 @@ -1,0 +2,14 @@ +Tue Aug 13 10:15:30 UTC 2013 - dmuel...@suse.com + +- update to 0.8.6: + - Do alternate type of checking for UNIX socket support, instead of checking + for platform == windows. + + - Functional tests now use multiprocessing module instead of subprocess module, + speeding up test suite and making concurrent execution more reliable. + + - Runner now appends the current working directory to ``sys.path`` to support + running WSGI applications from a directory (i.e., not installed in a + virtualenv). + +------------------------------------------------------------------- Old: ---- waitress-0.8.5.tar.gz New: ---- waitress-0.8.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-waitress.spec ++++++ --- /var/tmp/diff_new_pack.jMB0Tk/_old 2013-08-15 12:30:24.000000000 +0200 +++ /var/tmp/diff_new_pack.jMB0Tk/_new 2013-08-15 12:30:24.000000000 +0200 @@ -17,7 +17,7 @@ Name: python-waitress -Version: 0.8.5 +Version: 0.8.6 Release: 0 Summary: Waitress WSGI server License: ZPL-2.1 @@ -25,7 +25,7 @@ Url: https://github.com/Pylons/waitress Source: http://pypi.python.org/packages/source/w/waitress/waitress-%{version}.tar.gz BuildRequires: python-devel -BuildRequires: python-distribute +BuildRequires: python-setuptools # Test requirements: #BuildRequires: python-nose # Documentation requirements: ++++++ waitress-0.8.5.tar.gz -> waitress-0.8.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/CHANGES.txt new/waitress-0.8.6/CHANGES.txt --- old/waitress-0.8.5/CHANGES.txt 2013-05-28 02:55:45.000000000 +0200 +++ new/waitress-0.8.6/CHANGES.txt 2013-08-12 06:58:53.000000000 +0200 @@ -1,3 +1,24 @@ +0.8.6 (2013-08-12) +------------------ + +- Do alternate type of checking for UNIX socket support, instead of checking + for platform == windows. + +- Functional tests now use multiprocessing module instead of subprocess module, + speeding up test suite and making concurrent execution more reliable. + +- Runner now appends the current working directory to ``sys.path`` to support + running WSGI applications from a directory (i.e., not installed in a + virtualenv). + +- Add a ``url_prefix`` adjustment setting. You can use it by passing + ``script_name='/foo'`` to ``waitress.serve`` or you can use it in a + ``PasteDeploy`` ini file as ``script_name = /foo``. This will cause the WSGI + ``SCRIPT_NAME`` value to be the value passed minus any trailing slashes you + add, and it will cause the ``PATH_INFO`` of any request which is prefixed + with this value to be stripped of the prefix. You can use this instead of + PasteDeploy's ``prefixmiddleware`` to always prefix the path. + 0.8.5 (2013-05-27) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/CONTRIBUTORS.txt new/waitress-0.8.6/CONTRIBUTORS.txt --- old/waitress-0.8.5/CONTRIBUTORS.txt 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/CONTRIBUTORS.txt 2013-08-12 06:52:42.000000000 +0200 @@ -116,3 +116,5 @@ - Tshepang Lekhonkhobe, 2013/04/09 - Keith Gaughan, 2013/05/11 + +- Jamie Matthews, 2013/06/19 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/PKG-INFO new/waitress-0.8.6/PKG-INFO --- old/waitress-0.8.5/PKG-INFO 2013-05-28 02:56:52.000000000 +0200 +++ new/waitress-0.8.6/PKG-INFO 2013-08-12 07:02:59.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: waitress -Version: 0.8.5 +Version: 0.8.6 Summary: Waitress WSGI server Home-page: https://github.com/Pylons/waitress Author: Chris McDonough @@ -16,6 +16,27 @@ http://docs.pylonsproject.org/projects/waitress/en/latest/ . + 0.8.6 (2013-08-12) + ------------------ + + - Do alternate type of checking for UNIX socket support, instead of checking + for platform == windows. + + - Functional tests now use multiprocessing module instead of subprocess module, + speeding up test suite and making concurrent execution more reliable. + + - Runner now appends the current working directory to ``sys.path`` to support + running WSGI applications from a directory (i.e., not installed in a + virtualenv). + + - Add a ``url_prefix`` adjustment setting. You can use it by passing + ``script_name='/foo'`` to ``waitress.serve`` or you can use it in a + ``PasteDeploy`` ini file as ``script_name = /foo``. This will cause the WSGI + ``SCRIPT_NAME`` value to be the value passed minus any trailing slashes you + add, and it will cause the ``PATH_INFO`` of any request which is prefixed + with this value to be stripped of the prefix. You can use this instead of + PasteDeploy's ``prefixmiddleware`` to always prefix the path. + 0.8.5 (2013-05-27) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/docs/api.rst new/waitress-0.8.6/docs/api.rst --- old/waitress-0.8.5/docs/api.rst 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/docs/api.rst 2013-08-12 06:42:26.000000000 +0200 @@ -5,6 +5,6 @@ .. module:: waitress -.. function:: serve(app, host='0.0.0.0', port=8080, unix_socket=None, unix_socket_perms='600', threads=4, url_scheme='http', ident='waitress', backlog=1204, recv_bytes=8192, send_bytes=18000, outbuf_overflow=104856, inbuf_overflow=52488, connection_limit=1000, cleanup_interval=30, channel_timeout=120, log_socket_errors=True, max_request_header_size=262144, max_request_body_size=1073741824, expose_tracebacks=False) +.. function:: serve(app, host='0.0.0.0', port=8080, unix_socket=None, unix_socket_perms='600', threads=4, url_scheme='http', url_prefix='', ident='waitress', backlog=1204, recv_bytes=8192, send_bytes=18000, outbuf_overflow=104856, inbuf_overflow=52488, connection_limit=1000, cleanup_interval=30, channel_timeout=120, log_socket_errors=True, max_request_header_size=262144, max_request_body_size=1073741824, expose_tracebacks=False) See :ref:`arguments` for more information. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/docs/arguments.rst new/waitress-0.8.6/docs/arguments.rst --- old/waitress-0.8.5/docs/arguments.rst 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/docs/arguments.rst 2013-08-12 06:42:35.000000000 +0200 @@ -105,3 +105,17 @@ asyncore_loop_timeout The ``timeout`` value (seconds) passed to ``asyncore.loop`` to run the mainloop. Default: 1. (New in 0.8.3.) + +asyncore_use_poll + Boolean: switch from using select() to poll() in ``asyncore.loop``. + By default asyncore.loop() uses select() which has a limit of 1024 + file descriptors. Select() and poll() provide basically the same + functionality, but poll() doesn't have the file descriptors limit. + Default: False (New in 0.8.6) + +url_prefix + String: the value used as the WSGI ``SCRIPT_NAME`` value. Setting this to + anything except the empty string will cause the WSGI ``SCRIPT_NAME`` value + to be the value passed minus any trailing slashes you add, and it will + cause the ``PATH_INFO`` of any request which is prefixed with this value to + be stripped of the prefix. Default: the empty string. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/docs/conf.py new/waitress-0.8.6/docs/conf.py --- old/waitress-0.8.5/docs/conf.py 2013-05-28 02:56:04.000000000 +0200 +++ new/waitress-0.8.6/docs/conf.py 2013-08-12 07:00:18.000000000 +0200 @@ -65,7 +65,7 @@ # other places throughout the built documents. # # The short X.Y version. -version = '0.8.5' +version = '0.8.6' # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/docs/index.rst new/waitress-0.8.6/docs/index.rst --- old/waitress-0.8.5/docs/index.rst 2013-05-25 02:40:51.000000000 +0200 +++ new/waitress-0.8.6/docs/index.rst 2013-08-12 06:58:04.000000000 +0200 @@ -21,9 +21,18 @@ from waitress import serve serve(wsgiapp) - + Press Ctrl-C (or Ctrl-Break on Windows) to exit the server. +If you want to serve your application through a UNIX domain socket (to serve +a downstream HTTP server/proxy, e.g. nginx, lighttpd, etc.), call ``serve`` +with the ``unix_socket`` argument:: + + from waitress import serve + serve(wsgiapp, unix_socket='/path/to/unix.sock') + +Needless to say, this configuration won't work on Windows. + Exceptions generated by your application will be shown on the console by default. See :ref:`logging` to change this. @@ -35,6 +44,12 @@ host = 127.0.0.1 port = 8080 +The :term:`PasteDeploy` syntax for UNIX domain sockets is analagous:: + + [server:main] + use = egg:waitress#main + unix_socket = /path/to/unix.sock + You can find more settings to tweak (arguments to ``waitress.serve`` or equivalent settings in PasteDeploy) in :ref:`arguments`. @@ -123,6 +138,23 @@ This works if all URLs generated by your application should use the ``https`` scheme. +Using ``url_prefix`` to influence ``SCRIPT_NAME`` and ``PATH_INFO`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can have the Waitress server use a particular url prefix by default for all +URLs generated by downstream applications that take ``SCRIPT_NAME`` into +account.:: + + from waitress import serve + serve(wsgiapp, host='0.0.0.0', port=8080, url_prefix='/foo') + +Setting this to any value except the empty string will cause the WSGI +``SCRIPT_NAME`` value to be that value, minus any trailing slashes you add, and +it will cause the ``PATH_INFO`` of any request which is prefixed with this +value to be stripped of the prefix. This is useful in proxying scenarios where +you wish to forward all traffic to a Waitress server but need URLs generated by +downstream applications to be prefixed with a particular path segment. + Using Paste's ``PrefixMiddleware`` to set ``wsgi.url_scheme`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -182,6 +214,10 @@ host = 127.0.0.1 port = 8080 +Note that you can also set ``PATH_INFO`` and ``SCRIPT_NAME`` using +PrefixMiddleware too (its original purpose, really) instead of using Waitress' +``url_prefix`` adjustment. See the PasteDeploy docs for more information. + Extended Documentation ---------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/docs/runner.rst new/waitress-0.8.6/docs/runner.rst --- old/waitress-0.8.5/docs/runner.rst 2013-05-25 02:40:51.000000000 +0200 +++ new/waitress-0.8.6/docs/runner.rst 2013-08-12 06:58:29.000000000 +0200 @@ -56,6 +56,11 @@ Would load the ``myapp.mymodule`` module, and call ``app.wsgi_factory`` to get a WSGI application function to be passed to ``waitress.server``. +.. note:: + + As of 0.8.6, the current directory is automatically included on + ``sys.path``. + .. _invocation: Invocation @@ -93,6 +98,13 @@ ``--url-scheme=STR`` Default ``wsgi.url_scheme`` value, default is 'http'. +``--url-prefix=STR`` + The ``SCRIPT_NAME`` WSGI environment value. Setting this to anything + except the empty string will cause the WSGI ``SCRIPT_NAME`` value to be the + value passed minus any trailing slashes you add, and it will cause the + ``PATH_INFO`` of any request which is prefixed with this value to be + stripped of the prefix. Default is the empty string. + ``--ident=STR`` Server identity used in the 'Server' header in responses. Default is 'waitress'. @@ -150,3 +162,7 @@ ``--asyncore-loop-timeout=INT`` The timeout value in seconds passed to ``asyncore.loop()``. Default is 1. + +``--asyncore-use-poll`` + The use_poll argument passed to ``asyncore.loop()``. Helps overcome open + file descriptors limit. Default is False. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/setup.py new/waitress-0.8.6/setup.py --- old/waitress-0.8.5/setup.py 2013-05-28 02:55:54.000000000 +0200 +++ new/waitress-0.8.6/setup.py 2013-08-12 06:59:40.000000000 +0200 @@ -37,7 +37,7 @@ setup( name='waitress', - version='0.8.5', + version='0.8.6', author='Zope Foundation and Contributors', author_email='zope-...@zope.org', maintainer="Chris McDonough", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/__init__.py new/waitress-0.8.6/waitress/__init__.py --- old/waitress-0.8.5/waitress/__init__.py 2013-05-28 02:49:36.000000000 +0200 +++ new/waitress-0.8.6/waitress/__init__.py 2013-08-12 06:11:19.000000000 +0200 @@ -1,4 +1,4 @@ -from waitress.server import WSGIServer, create_server +from waitress.server import create_server import logging def serve(app, **kw): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/adjustments.py new/waitress-0.8.6/waitress/adjustments.py --- old/waitress-0.8.5/waitress/adjustments.py 2013-05-25 02:40:51.000000000 +0200 +++ new/waitress-0.8.6/waitress/adjustments.py 2013-08-12 06:44:02.000000000 +0200 @@ -36,6 +36,9 @@ """Convert the given octal string to an actual number.""" return int(s, 8) +def slash_suffix_stripped_str(s): + return s.rstrip('/') + class Adjustments(object): """This class contains tunable parameters. """ @@ -45,6 +48,7 @@ ('port', int), ('threads', int), ('url_scheme', str), + ('url_prefix', slash_suffix_stripped_str), ('backlog', int), ('recv_bytes', int), ('send_bytes', int), @@ -59,6 +63,7 @@ ('expose_tracebacks', asbool), ('ident', str), ('asyncore_loop_timeout', int), + ('asyncore_use_poll', asbool), ('unix_socket', str), ('unix_socket_perms', asoctal), ) @@ -77,6 +82,10 @@ # default ``wsgi.url_scheme`` value url_scheme = 'http' + # default ``SCRIPT_NAME`` value, also helps reset ``PATH_INFO`` + # when nonempty + url_prefix = '' + # server identity (sent in Server: header) ident = 'waitress' @@ -153,6 +162,9 @@ # The asyncore.loop timeout value asyncore_loop_timeout = 1 + # The asyncore.loop flag to use poll() instead of the default select(). + asyncore_use_poll = False + def __init__(self, **kw): for k, v in kw.items(): if k not in self._param_map: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/runner.py new/waitress-0.8.6/waitress/runner.py --- old/waitress-0.8.5/waitress/runner.py 2013-05-28 02:54:51.000000000 +0200 +++ new/waitress-0.8.6/waitress/runner.py 2013-08-12 06:52:42.000000000 +0200 @@ -17,6 +17,7 @@ from __future__ import print_function, unicode_literals import getopt +import os import os.path import re import sys @@ -57,6 +58,13 @@ --url-scheme=STR Default wsgi.url_scheme value, default is 'http'. + --url-prefix=STR + The ``SCRIPT_NAME`` WSGI environment value. Setting this to anything + except the empty string will cause the WSGI ``SCRIPT_NAME`` value to be + the value passed minus any trailing slashes you add, and it will cause + the ``PATH_INFO`` of any request which is prefixed with this value to + be stripped of the prefix. Default is the empty string. + --ident=STR Server identity used in the 'Server' header in responses. Default is 'waitress'. @@ -115,6 +123,11 @@ --asyncore-loop-timeout=INT The timeout value in seconds passed to asyncore.loop(). Default is 1. + + --asyncore-use-poll + The use_poll argument passed to ``asyncore.loop()``. Helps overcome + open file descriptors limit. Default is False. + """ RUNNER_PATTERN = re.compile(r""" @@ -153,7 +166,7 @@ obj = getattr(obj, segment) return obj -def show_help(stream, name, error=None): # pragma: no cover +def show_help(stream, name, error=None): # pragma: no cover if error is not None: print('Error: {0}\n'.format(error), file=stream) print(HELP.format(name), file=stream) @@ -182,6 +195,9 @@ show_help(sys.stderr, name, str(exc)) return 1 + # Add the current directory onto sys.path + sys.path.append(os.getcwd()) + # Get the WSGI function. try: app = resolve(module, obj_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/server.py new/waitress-0.8.6/waitress/server.py --- old/waitress-0.8.5/waitress/server.py 2013-05-28 02:49:36.000000000 +0200 +++ new/waitress-0.8.6/waitress/server.py 2013-08-12 06:11:29.000000000 +0200 @@ -37,7 +37,7 @@ server.run() """ adj = Adjustments(**kw) - if adj.unix_socket: + if adj.unix_socket and hasattr(socket, 'AF_UNIX'): cls = UnixWSGIServer else: cls = TcpWSGIServer @@ -150,7 +150,8 @@ try: self.asyncore.loop( timeout=self.adj.asyncore_loop_timeout, - map=self._map + map=self._map, + use_poll=self.adj.asyncore_use_poll, ) except (SystemExit, KeyboardInterrupt): self.task_dispatcher.shutdown() @@ -189,25 +190,23 @@ for (level, optname, value) in self.adj.socket_options: conn.setsockopt(level, optname, value) -class UnixWSGIServer(BaseWSGIServer): +if hasattr(socket, 'AF_UNIX'): - @property - def family(self): - # Windows doesnt support AF_UNIX, so hide in property so we don't fail - # at import time on it. - return socket.AF_UNIX + class UnixWSGIServer(BaseWSGIServer): - def bind_server_socket(self): - cleanup_unix_socket(self.adj.unix_socket) - self.bind(self.adj.unix_socket) - if os.path.exists(self.adj.unix_socket): - os.chmod(self.adj.unix_socket, self.adj.unix_socket_perms) + family = socket.AF_UNIX - def getsockname(self): - return ('unix', self.socket.getsockname()) + def bind_server_socket(self): + cleanup_unix_socket(self.adj.unix_socket) + self.bind(self.adj.unix_socket) + if os.path.exists(self.adj.unix_socket): + os.chmod(self.adj.unix_socket, self.adj.unix_socket_perms) - def fix_addr(self, addr): - return ('localhost', None) + def getsockname(self): + return ('unix', self.socket.getsockname()) + + def fix_addr(self, addr): + return ('localhost', None) # Compatibility alias. WSGIServer = TcpWSGIServer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/task.py new/waitress-0.8.6/waitress/task.py --- old/waitress-0.8.5/waitress/task.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/task.py 2013-08-12 06:42:57.000000000 +0200 @@ -442,8 +442,12 @@ channel = self.channel server = channel.server - while path and path.startswith('/'): - path = path[1:] + path = path.lstrip('/') + + url_prefix_with_slash = server.adj.url_prefix.lstrip('/') + '/' + + if url_prefix_with_slash and path.startswith(url_prefix_with_slash): + path = path[len(url_prefix_with_slash):] environ = {} environ['REQUEST_METHOD'] = request.command.upper() @@ -451,7 +455,7 @@ environ['SERVER_NAME'] = server.server_name environ['SERVER_SOFTWARE'] = server.adj.ident environ['SERVER_PROTOCOL'] = 'HTTP/%s' % self.version - environ['SCRIPT_NAME'] = '' + environ['SCRIPT_NAME'] = server.adj.url_prefix environ['PATH_INFO'] = '/' + path environ['QUERY_STRING'] = request.query environ['REMOTE_ADDR'] = channel.addr[0] @@ -461,7 +465,7 @@ mykey = rename_headers.get(key, None) if mykey is None: mykey = 'HTTP_%s' % key - if not mykey in environ: + if mykey not in environ: environ[mykey] = value # the following environment variables are required by the WSGI spec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/badcl.py new/waitress-0.8.6/waitress/tests/fixtureapps/badcl.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/badcl.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/badcl.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,4 +1,4 @@ -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover body = b'abcdefghi' cl = len(body) if environ['PATH_INFO'] == '/short_body': @@ -10,7 +10,3 @@ [('Content-Length', str(cl)), ('Content-Type', 'text/plain')] ) return [body] - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/echo.py new/waitress-0.8.6/waitress/tests/fixtureapps/echo.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/echo.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/echo.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,4 +1,4 @@ -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover cl = environ.get('CONTENT_LENGTH', None) if cl is not None: cl = int(cl) @@ -9,7 +9,3 @@ [('Content-Length', cl), ('Content-Type', 'text/plain')] ) return [body] - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/error.py new/waitress-0.8.6/waitress/tests/fixtureapps/error.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/error.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/error.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,4 +1,4 @@ -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover cl = environ.get('CONTENT_LENGTH', None) if cl is not None: cl = int(cl) @@ -18,7 +18,3 @@ raise ValueError return foo() raise ValueError('wrong') - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app, expose_tracebacks=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/filewrapper.py new/waitress-0.8.6/waitress/tests/fixtureapps/filewrapper.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/filewrapper.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/filewrapper.py 2013-05-28 04:43:09.000000000 +0200 @@ -3,7 +3,7 @@ here = os.path.dirname(os.path.abspath(__file__)) fn = os.path.join(here, 'groundhog1.jpg') -class KindaFilelike(object): +class KindaFilelike(object): # pragma: no cover def __init__(self, bytes): self.bytes = bytes @@ -13,7 +13,7 @@ self.bytes = self.bytes[n:] return bytes -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover path_info = environ['PATH_INFO'] if path_info.startswith('/filelike'): f = open(fn, 'rb') @@ -68,7 +68,3 @@ headers ) return environ['wsgi.file_wrapper'](f, 8192) - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/nocl.py new/waitress-0.8.6/waitress/tests/fixtureapps/nocl.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/nocl.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/nocl.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,14 +1,14 @@ -def chunks(l, n): +def chunks(l, n): # pragma: no cover """ Yield successive n-sized chunks from l. """ for i in range(0, len(l), n): yield l[i:i + n] -def gen(body): +def gen(body): # pragma: no cover for chunk in chunks(body, 10): yield chunk -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover cl = environ.get('CONTENT_LENGTH', None) if cl is not None: cl = int(cl) @@ -22,7 +22,3 @@ if environ['PATH_INFO'] == '/list_lentwo': return [body[0:1], body[1:]] return gen(body) - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app, expose_tracebacks=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/sleepy.py new/waitress-0.8.6/waitress/tests/fixtureapps/sleepy.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/sleepy.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/sleepy.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,6 +1,6 @@ import time -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover if environ['PATH_INFO'] == '/sleepy': time.sleep(2) body = b'sleepy returned' @@ -12,7 +12,3 @@ [('Content-Length', cl), ('Content-Type', 'text/plain')] ) return [body] - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/toolarge.py new/waitress-0.8.6/waitress/tests/fixtureapps/toolarge.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/toolarge.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/toolarge.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,4 +1,4 @@ -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover body = b'abcdef' cl = len(body) start_response( @@ -6,7 +6,3 @@ [('Content-Length', str(cl)), ('Content-Type', 'text/plain')] ) return [body] - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app, max_request_header_size=1000, max_request_body_size=1000) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/fixtureapps/writecb.py new/waitress-0.8.6/waitress/tests/fixtureapps/writecb.py --- old/waitress-0.8.5/waitress/tests/fixtureapps/writecb.py 2013-05-12 04:41:05.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/fixtureapps/writecb.py 2013-05-28 04:43:09.000000000 +0200 @@ -1,4 +1,4 @@ -def app(environ, start_response): +def app(environ, start_response): # pragma: no cover path_info = environ['PATH_INFO'] if path_info == '/no_content_length': headers = [] @@ -12,7 +12,3 @@ else: write(b'abcdefghi') return [] - -if __name__ == '__main__': - from waitress.tests.support import start_server - start_server(app) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/support.py new/waitress-0.8.6/waitress/tests/support.py --- old/waitress-0.8.5/waitress/tests/support.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/support.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,39 +0,0 @@ -""" -Support code for tests. -""" - -import getopt -import logging -import sys - -import waitress - - -class NullHandler(logging.Handler): # pragma: no cover - """A logging handler that swallows all emitted messages. - """ - def emit(self, record): - pass - -def start_server(app, **kwargs): # pragma: no cover - """Run a fixture application. - - There are three flags: `-p` to specify a port to listen on, `-u` to - specify a Unix socket to listen on, and `-v` prevent logging from being - disabled. - """ - opts, _args = getopt.getopt(sys.argv[1:], 'p:u:v') - quiet = True - for opt, value in opts: - if opt == '-p': - kwargs['port'] = int(value) - elif opt == '-u': - kwargs.update({ - 'unix_socket': value, - 'unix_socket_perms': '600', - }) - elif opt == '-v': - quiet = False - if quiet: - logging.getLogger('waitress').addHandler(NullHandler()) - waitress.serve(app, _quiet=quiet, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/test_adjustments.py new/waitress-0.8.6/waitress/tests/test_adjustments.py --- old/waitress-0.8.5/waitress/tests/test_adjustments.py 2013-05-25 02:40:51.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/test_adjustments.py 2013-08-12 06:45:42.000000000 +0200 @@ -58,7 +58,8 @@ channel_timeout='1200', log_socket_errors='true', max_request_header_size='1300', max_request_body_size='1400', expose_tracebacks='true', ident='abc', asyncore_loop_timeout='5', - unix_socket='/tmp/waitress.sock', unix_socket_perms='777') + asyncore_use_poll=True, unix_socket='/tmp/waitress.sock', + unix_socket_perms='777', url_prefix='/foo') self.assertEqual(inst.host, 'host') self.assertEqual(inst.port, 8080) self.assertEqual(inst.threads, 5) @@ -76,9 +77,11 @@ self.assertEqual(inst.max_request_body_size, 1400) self.assertEqual(inst.expose_tracebacks, True) self.assertEqual(inst.asyncore_loop_timeout, 5) + self.assertEqual(inst.asyncore_use_poll, True) self.assertEqual(inst.ident, 'abc') self.assertEqual(inst.unix_socket, '/tmp/waitress.sock') self.assertEqual(inst.unix_socket_perms, 0o777) + self.assertEqual(inst.url_prefix, '/foo') def test_badvar(self): self.assertRaises(ValueError, self._makeOne, nope=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/test_functional.py new/waitress-0.8.6/waitress/tests/test_functional.py --- old/waitress-0.8.5/waitress/tests/test_functional.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/test_functional.py 2013-06-10 05:15:01.000000000 +0200 @@ -1,4 +1,6 @@ import errno +import logging +import multiprocessing import os import socket import string @@ -6,6 +8,7 @@ import sys import time import unittest +from waitress import server from waitress.compat import ( httplib, tobytes @@ -15,6 +18,28 @@ dn = os.path.dirname here = dn(__file__) +class NullHandler(logging.Handler): # pragma: no cover + """A logging handler that swallows all emitted messages. + """ + def emit(self, record): + pass + +def start_server(app, svr, queue, **kwargs): # pragma: no cover + """Run a fixture application. + """ + logging.getLogger('waitress').addHandler(NullHandler()) + svr(app, queue, **kwargs).run() + +class FixtureTcpWSGIServer(server.TcpWSGIServer): + """A version of TcpWSGIServer that relays back what it's bound to. + """ + + def __init__(self, application, queue, **kw): # pragma: no cover + # Coverage doesn't see this as it's ran in a separate process. + kw['port'] = 0 # Bind to any available port. + super(FixtureTcpWSGIServer, self).__init__(application, **kw) + queue.put(self.socket.getsockname()) + class SubprocessTests(object): # For nose: all tests may be ran in separate processes. @@ -22,15 +47,25 @@ exe = sys.executable - def start_subprocess(self, cmd): + server = None + + def start_subprocess(self, target, **kw): + # Spawn a server process. + queue = multiprocessing.Queue() + self.proc = multiprocessing.Process( + target=start_server, + args=(target, self.server, queue), + kwargs=kw, + ) + self.proc.start() + if self.proc.exitcode is not None: # pragma: no cover + raise RuntimeError("%s didn't start" % str(target)) + # Get the socket the server is listening on. + self.bound_to = queue.get(timeout=5) self.sock = self.create_socket() - self.proc = subprocess.Popen(cmd) - time.sleep(.5) - if self.proc.returncode is not None: # pragma: no cover - raise RuntimeError('%s didnt start' % str(cmd)) def stop_subprocess(self): - if self.proc.returncode is None: + if self.proc.exitcode is None: self.proc.terminate() self.sock.close() @@ -41,10 +76,10 @@ self.assertEqual(v, tobytes(version)) def create_socket(self): - raise NotImplementedError # pragma: no cover + return socket.socket(self.server.family, socket.SOCK_STREAM) def connect(self): - raise NotImplementedError # pragma: no cover + self.sock.connect(self.bound_to) def make_http_connection(self): raise NotImplementedError # pragma: no cover @@ -54,62 +89,17 @@ class TcpTests(SubprocessTests): - @property - def port(self): - # To permit parallel testing, use a PID-dependent port: - # Subtract least-significant 20 bits of the PID from the top of the - # allowed port range. - return 0xffff - (os.getpid() & 0x7ff) - - def create_socket(self): - return socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - def connect(self): - self.sock.connect(('127.0.0.1', self.port)) + server = FixtureTcpWSGIServer def make_http_connection(self): - return httplib.HTTPConnection('127.0.0.1', self.port) - - def start_subprocess(self, cmd): - super(TcpTests, self).start_subprocess(cmd + ['-p', str(self.port)]) - -class UnixTests(SubprocessTests): - - @property - def path(self): - # To permit parallel testing, use a PID-dependent socket. - return '/tmp/waitress.test-%d.sock' % os.getpid() - - def create_socket(self): - return socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - - def connect(self): - self.sock.connect(self.path) - - def make_http_connection(self): - return UnixHTTPConnection(self.path) - - def start_subprocess(self, cmd): - super(UnixTests, self).start_subprocess(cmd + ['-u', self.path]) - - def stop_subprocess(self): - super(UnixTests, self).stop_subprocess() - cleanup_unix_socket(self.path) - - def send_check_error(self, to_send): - # Unlike inet domain sockets, Unix domain sockets can trigger a - # 'Broken pipe' error when the socket it closed. - try: - self.sock.send(to_send) - except socket.error as exc: - self.assertEqual(get_errno(exc), errno.EPIPE) + return httplib.HTTPConnection(*self.bound_to) class SleepyThreadTests(TcpTests, unittest.TestCase): # test that sleepy thread doesnt block other requests def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'sleepy.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import sleepy + self.start_subprocess(sleepy.app) def tearDown(self): self.stop_subprocess() @@ -117,8 +107,8 @@ def test_it(self): getline = os.path.join(here, 'fixtureapps', 'getline.py') cmds = ( - [self.exe, getline, 'http://127.0.0.1:%d/sleepy' % self.port], - [self.exe, getline, 'http://127.0.0.1:%d/' % self.port] + [self.exe, getline, 'http://%s:%d/sleepy' % self.bound_to], + [self.exe, getline, 'http://%s:%d/' % self.bound_to] ) r, w = os.pipe() procs = [] @@ -139,8 +129,8 @@ class EchoTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'echo.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import echo + self.start_subprocess(echo.app) def tearDown(self): self.stop_subprocess() @@ -221,7 +211,7 @@ fp = self.sock.makefile('rb', 0) line, headers, response_body = read_http(fp) self.assertline(line, '200', 'OK', 'HTTP/1.0') - headers['content-length'] + self.assertEqual(int(headers['content-length']), len(data)) self.assertEqual(len(response_body), len(data)) self.assertEqual(response_body, tobytes(data)) @@ -404,8 +394,8 @@ class PipeliningTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'echo.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import echo + self.start_subprocess(echo.app) def tearDown(self): self.stop_subprocess() @@ -443,8 +433,8 @@ class ExpectContinueTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'echo.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import echo + self.start_subprocess(echo.app) def tearDown(self): self.stop_subprocess() @@ -481,8 +471,8 @@ class BadContentLengthTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'badcl.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import badcl + self.start_subprocess(badcl.app) def tearDown(self): self.stop_subprocess() @@ -546,8 +536,8 @@ class NoContentLengthTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'nocl.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import nocl + self.start_subprocess(nocl.app) def tearDown(self): self.stop_subprocess() @@ -679,8 +669,8 @@ class WriteCallbackTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'writecb.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import writecb + self.start_subprocess(writecb.app) def tearDown(self): self.stop_subprocess() @@ -781,8 +771,10 @@ toobig = 1050 def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'toolarge.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import toolarge + self.start_subprocess(toolarge.app, + max_request_header_size=1000, + max_request_body_size=1000) def tearDown(self): self.stop_subprocess() @@ -979,8 +971,8 @@ class InternalServerErrorTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'error.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import error + self.start_subprocess(error.app, expose_tracebacks=True) def tearDown(self): self.stop_subprocess() @@ -1044,8 +1036,8 @@ class FileWrapperTests(object): def setUp(self): - echo = os.path.join(here, 'fixtureapps', 'filewrapper.py') - self.start_subprocess([self.exe, echo]) + from waitress.tests.fixtureapps import filewrapper + self.start_subprocess(filewrapper.app) def tearDown(self): self.stop_subprocess() @@ -1300,7 +1292,37 @@ class TcpFileWrapperTests(FileWrapperTests, TcpTests, unittest.TestCase): pass -if not sys.platform.startswith('win'): +if hasattr(socket, 'AF_UNIX'): + + class FixtureUnixWSGIServer(server.UnixWSGIServer): + """A version of UnixWSGIServer that relays back what it's bound to. + """ + + def __init__(self, application, queue, **kw): # pragma: no cover + # Coverage doesn't see this as it's ran in a separate process. + # To permit parallel testing, use a PID-dependent socket. + kw['unix_socket'] = '/tmp/waitress.test-%d.sock' % os.getpid() + super(FixtureUnixWSGIServer, self).__init__(application, **kw) + queue.put(self.socket.getsockname()) + + class UnixTests(SubprocessTests): + + server = FixtureUnixWSGIServer + + def make_http_connection(self): + return UnixHTTPConnection(self.bound_to) + + def stop_subprocess(self): + super(UnixTests, self).stop_subprocess() + cleanup_unix_socket(self.bound_to) + + def send_check_error(self, to_send): + # Unlike inet domain sockets, Unix domain sockets can trigger a + # 'Broken pipe' error when the socket it closed. + try: + self.sock.send(to_send) + except socket.error as exc: + self.assertEqual(get_errno(exc), errno.EPIPE) class UnixEchoTests(EchoTests, UnixTests, unittest.TestCase): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/test_runner.py new/waitress-0.8.6/waitress/tests/test_runner.py --- old/waitress-0.8.5/waitress/tests/test_runner.py 2013-05-25 02:40:51.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/test_runner.py 2013-08-12 06:52:42.000000000 +0200 @@ -1,4 +1,5 @@ import contextlib +import os import sys if sys.version_info[:2] == (2, 6): # pragma: no cover @@ -99,6 +100,22 @@ 1, "^Error: Bad module 'nonexistent'") + def test_cwd_added_to_path(self): + def null_serve(app, **kw): + pass + sys_path = sys.path + current_dir = os.getcwd() + try: + os.chdir(os.path.dirname(__file__)) + argv = [ + 'waitress-serve', + 'fixtureapps.runner:app', + ] + self.assertEqual(runner.run(argv=argv, _serve=null_serve), 0) + finally: + sys.path = sys_path + os.chdir(current_dir) + def test_bad_app_object(self): self.match_output( ['waitress.tests.fixtureapps.runner:a'], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/test_server.py new/waitress-0.8.6/waitress/tests/test_server.py --- old/waitress-0.8.5/waitress/tests/test_server.py 2013-05-28 02:49:36.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/test_server.py 2013-06-10 05:15:01.000000000 +0200 @@ -1,6 +1,5 @@ import errno import socket -import sys import unittest class TestWSGIServer(unittest.TestCase): @@ -191,7 +190,7 @@ self.assertNotEqual(Adjustments.port, 1234) self.assertEqual(inst.adj.port, 1234) -if not sys.platform.startswith('win'): +if hasattr(socket, 'AF_UNIX'): class TestUnixWSGIServer(unittest.TestCase): unix_socket = '/tmp/waitress.test.sock' @@ -311,7 +310,7 @@ class DummyAsyncore(object): - def loop(self, timeout=None, map=None): + def loop(self, timeout=30.0, use_poll=False, map=None, count=None): raise SystemExit class DummyTrigger(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress/tests/test_task.py new/waitress-0.8.6/waitress/tests/test_task.py --- old/waitress-0.8.5/waitress/tests/test_task.py 2013-05-24 01:02:12.000000000 +0200 +++ new/waitress-0.8.6/waitress/tests/test_task.py 2013-08-12 06:44:22.000000000 +0200 @@ -565,6 +565,26 @@ environ = inst.get_environment() self.assertEqual(environ['QUERY_STRING'], 'abc') + def test_get_environ_with_url_prefix_miss(self): + inst = self._makeOne() + inst.channel.server.adj.url_prefix = '/foo' + request = DummyParser() + request.path = '/bar' + inst.request = request + environ = inst.get_environment() + self.assertEqual(environ['PATH_INFO'], '/bar') + self.assertEqual(environ['SCRIPT_NAME'], '/foo') + + def test_get_environ_with_url_prefix_hit(self): + inst = self._makeOne() + inst.channel.server.adj.url_prefix = '/foo' + request = DummyParser() + request.path = '/foo/fuz' + inst.request = request + environ = inst.get_environment() + self.assertEqual(environ['PATH_INFO'], '/fuz') + self.assertEqual(environ['SCRIPT_NAME'], '/foo') + def test_get_environment_values(self): import sys inst = self._makeOne() @@ -655,6 +675,7 @@ ident = 'waitress' host = '127.0.0.1' port = 80 + url_prefix = '' class DummyServer(object): server_name = 'localhost' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress.egg-info/PKG-INFO new/waitress-0.8.6/waitress.egg-info/PKG-INFO --- old/waitress-0.8.5/waitress.egg-info/PKG-INFO 2013-05-28 02:56:50.000000000 +0200 +++ new/waitress-0.8.6/waitress.egg-info/PKG-INFO 2013-08-12 07:02:57.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: waitress -Version: 0.8.5 +Version: 0.8.6 Summary: Waitress WSGI server Home-page: https://github.com/Pylons/waitress Author: Chris McDonough @@ -16,6 +16,27 @@ http://docs.pylonsproject.org/projects/waitress/en/latest/ . + 0.8.6 (2013-08-12) + ------------------ + + - Do alternate type of checking for UNIX socket support, instead of checking + for platform == windows. + + - Functional tests now use multiprocessing module instead of subprocess module, + speeding up test suite and making concurrent execution more reliable. + + - Runner now appends the current working directory to ``sys.path`` to support + running WSGI applications from a directory (i.e., not installed in a + virtualenv). + + - Add a ``url_prefix`` adjustment setting. You can use it by passing + ``script_name='/foo'`` to ``waitress.serve`` or you can use it in a + ``PasteDeploy`` ini file as ``script_name = /foo``. This will cause the WSGI + ``SCRIPT_NAME`` value to be the value passed minus any trailing slashes you + add, and it will cause the ``PATH_INFO`` of any request which is prefixed + with this value to be stripped of the prefix. You can use this instead of + PasteDeploy's ``prefixmiddleware`` to always prefix the path. + 0.8.5 (2013-05-27) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/waitress-0.8.5/waitress.egg-info/SOURCES.txt new/waitress-0.8.6/waitress.egg-info/SOURCES.txt --- old/waitress-0.8.5/waitress.egg-info/SOURCES.txt 2013-05-28 02:56:52.000000000 +0200 +++ new/waitress-0.8.6/waitress.egg-info/SOURCES.txt 2013-08-12 07:02:59.000000000 +0200 @@ -40,7 +40,6 @@ waitress.egg-info/requires.txt waitress.egg-info/top_level.txt waitress/tests/__init__.py -waitress/tests/support.py waitress/tests/test_adjustments.py waitress/tests/test_buffers.py waitress/tests/test_channel.py -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org