Imported Debian patch 0.9.1+dfsg-1
Piotr Ożarowski
10 years ago
0 | 0 | Werkzeug Changelog |
1 | 1 | ================== |
2 | ||
3 | Version 0.9.1 | |
4 | ------------- | |
5 | ||
6 | (bugfix release, released on June 14th 2013) | |
7 | ||
8 | - Fixed an issue with integers no longer being accepted in certain | |
9 | parts of the routing system or URL quoting functions. | |
10 | - Fixed an issue with `url_quote` not producing the right escape | |
11 | codes for single digit codepoints. | |
12 | - Fixed an issue with :class:`~werkzeug.wsgi.SharedDataMiddleware` not | |
13 | reading the path correctly and breaking on etag generation in some | |
14 | cases. | |
15 | - Properly handle `Expect: 100-continue` in the development server | |
16 | to resolve issues with curl. | |
17 | - Automatically exhaust the input stream on request close. This should | |
18 | fix issues where not touching request files results in a timeout. | |
19 | - Fixed exhausting of streams not doing anything if a non-limited | |
20 | stream was passed into the multipart parser. | |
21 | - Raised the buffer sizes for the multipart parser. | |
2 | 22 | |
3 | 23 | Version 0.9 |
4 | 24 | ----------- |
0 | 0 | Metadata-Version: 1.0 |
1 | 1 | Name: Werkzeug |
2 | Version: 0.9 | |
2 | Version: 0.9.1 | |
3 | 3 | Summary: The Swiss Army knife of Python web development |
4 | 4 | Home-page: http://werkzeug.pocoo.org/ |
5 | 5 | Author: Armin Ronacher |
0 | Werkzeug | |
1 | ======== | |
2 | ||
3 | Werkzeug started as simple collection of various utilities for WSGI | |
4 | applications and has become one of the most advanced WSGI utility | |
5 | modules. It includes a powerful debugger, full-featured request and | |
6 | response objects, HTTP utilities to handle entity tags, cache control | |
7 | headers, HTTP dates, cookie handling, file uploads, a powerful URL | |
8 | routing system and a bunch of community-contributed addon modules. | |
9 | ||
10 | Werkzeug is unicode aware and doesn't enforce a specific template | |
11 | engine, database adapter or anything else. It doesn't even enforce | |
12 | a specific way of handling requests and leaves all that up to the | |
13 | developer. It's most useful for end user applications which should work | |
14 | on as many server environments as possible (such as blogs, wikis, | |
15 | bulletin boards, etc.). | |
16 | ||
17 | Details and example applications are available on the | |
18 | `Werkzeug website <http://werkzeug.pocoo.org/>`_. |
0 | 0 | Metadata-Version: 1.0 |
1 | 1 | Name: Werkzeug |
2 | Version: 0.9 | |
2 | Version: 0.9.1 | |
3 | 3 | Summary: The Swiss Army knife of Python web development |
4 | 4 | Home-page: http://werkzeug.pocoo.org/ |
5 | 5 | Author: Armin Ronacher |
2 | 2 | LICENSE |
3 | 3 | MANIFEST.in |
4 | 4 | Makefile |
5 | README.rst | |
6 | 5 | setup.cfg |
7 | 6 | setup.py |
8 | 7 | Werkzeug.egg-info/PKG-INFO |
0 | python-werkzeug (0.9.1+dfsg-1) unstable; urgency=low | |
1 | ||
2 | * New upstream release | |
3 | * Run tests with LC_ALL=C.UTF-8 | |
4 | ||
5 | -- Piotr Ożarowski <piotr@debian.org> Sun, 16 Jun 2013 11:51:23 +0200 | |
6 | ||
0 | 7 | python-werkzeug (0.9+dfsg-1) unstable; urgency=low |
1 | 8 | |
2 | 9 | [ Piotr Ożarowski ] |
31 | 31 | # run-tests.py is not included in the tarball |
32 | 32 | # TODO: run tests for all supported Python versions |
33 | 33 | ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) |
34 | python -c 'from werkzeug.testsuite import main; main()' | |
34 | LC_ALL=C.UTF-8 python -c 'from werkzeug.testsuite import main; main()' | |
35 | 35 | endif |
36 | 36 | |
37 | 37 | clean: |
60 | 60 | |
61 | 61 | setup( |
62 | 62 | name='Werkzeug', |
63 | version='0.9', | |
63 | version='0.9.1', | |
64 | 64 | url='http://werkzeug.pocoo.org/', |
65 | 65 | license='BSD', |
66 | 66 | author='Armin Ronacher', |
19 | 19 | from werkzeug._compat import iteritems |
20 | 20 | |
21 | 21 | # the version. Usually set automatically by a script. |
22 | __version__ = '0.9' | |
22 | __version__ = '0.9.1' | |
23 | 23 | |
24 | 24 | |
25 | 25 | # This import magic raises concerns quite often which is why the implementation |
100 | 100 | exhaust = getattr(stream, 'exhaust', None) |
101 | 101 | if exhaust is not None: |
102 | 102 | exhaust() |
103 | else: | |
104 | while 1: | |
105 | chunk = stream.read(1024 * 64) | |
106 | if not chunk: | |
107 | break | |
103 | 108 | return update_wrapper(wrapper, f) |
104 | 109 | |
105 | 110 | |
275 | 280 | class MultiPartParser(object): |
276 | 281 | |
277 | 282 | def __init__(self, stream_factory=None, charset='utf-8', errors='replace', |
278 | max_form_memory_size=None, cls=None, buffer_size=10 * 1024): | |
283 | max_form_memory_size=None, cls=None, buffer_size=64 * 1024): | |
279 | 284 | self.stream_factory = stream_factory |
280 | 285 | self.charset = charset |
281 | 286 | self.errors = errors |
838 | 838 | return value |
839 | 839 | |
840 | 840 | def to_url(self, value): |
841 | return url_quote(to_bytes(value, self.map.charset)) | |
841 | return url_quote(value, charset=self.map.charset) | |
842 | 842 | |
843 | 843 | |
844 | 844 | class UnicodeConverter(BaseConverter): |
114 | 114 | return environ |
115 | 115 | |
116 | 116 | def run_wsgi(self): |
117 | if self.headers.get('Expect', '').lower().strip() == '100-continue': | |
118 | self.wfile.write(b'HTTP/1.1 100 Continue\r\n\r\n') | |
119 | ||
117 | 120 | environ = self.make_environ() |
118 | 121 | headers_set = [] |
119 | 122 | headers_sent = [] |
13 | 13 | import re |
14 | 14 | import sys |
15 | 15 | import unittest |
16 | import shutil | |
17 | import tempfile | |
18 | import atexit | |
16 | 19 | |
17 | 20 | from werkzeug.utils import find_modules |
18 | 21 | from werkzeug._compat import text_type, integer_types, reraise |
22 | ||
23 | ||
24 | def get_temporary_directory(): | |
25 | directory = tempfile.mkdtemp() | |
26 | @atexit.register | |
27 | def remove_directory(): | |
28 | try: | |
29 | shutil.rmtree(directory) | |
30 | except EnvironmentError: | |
31 | pass | |
32 | return directory | |
19 | 33 | |
20 | 34 | |
21 | 35 | def iter_suites(package): |
358 | 358 | ('/test4-meh', '', 'test4baz') |
359 | 359 | ]) |
360 | 360 | |
361 | def test_non_string_parts(self): | |
362 | m = r.Map([ | |
363 | r.Rule('/<foo>', endpoint='foo') | |
364 | ]) | |
365 | a = m.bind('example.com') | |
366 | self.assert_equal(a.build('foo', {'foo': 42}), '/42') | |
367 | ||
361 | 368 | def test_complex_routing_rules(self): |
362 | 369 | m = r.Map([ |
363 | 370 | r.Rule('/', endpoint='index'), |
34 | 34 | self.assert_strict_equal(urls.url_encode({u'a': None, u'b': u'foo bar'}), 'b=foo+bar') |
35 | 35 | self.assert_strict_equal(urls.url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)'), |
36 | 36 | 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)') |
37 | self.assert_strict_equal(urls.url_quote_plus(42), '42') | |
38 | self.assert_strict_equal(urls.url_quote(b'\xff'), '%FF') | |
37 | 39 | |
38 | 40 | def test_bytes_unquoting(self): |
39 | 41 | self.assert_strict_equal(urls.url_unquote(urls.url_quote( |
11 | 11 | from os import path |
12 | 12 | from contextlib import closing |
13 | 13 | |
14 | from werkzeug.testsuite import WerkzeugTestCase | |
14 | from werkzeug.testsuite import WerkzeugTestCase, get_temporary_directory | |
15 | 15 | |
16 | 16 | from werkzeug.wrappers import BaseResponse |
17 | 17 | from werkzeug.exceptions import BadRequest, ClientDisconnected |
18 | 18 | from werkzeug.test import Client, create_environ, run_wsgi_app |
19 | 19 | from werkzeug import wsgi |
20 | from werkzeug._compat import StringIO, BytesIO, NativeStringIO | |
20 | from werkzeug._compat import StringIO, BytesIO, NativeStringIO, to_native | |
21 | 21 | |
22 | 22 | |
23 | 23 | class WSGIUtilsTestCase(WerkzeugTestCase): |
30 | 30 | def null_application(environ, start_response): |
31 | 31 | start_response('404 NOT FOUND', [('Content-Type', 'text/plain')]) |
32 | 32 | yield b'NOT FOUND' |
33 | ||
34 | test_dir = get_temporary_directory() | |
35 | with open(path.join(test_dir, to_native(u'äöü', 'utf-8')), 'w') as test_file: | |
36 | test_file.write(u'FOUND') | |
37 | ||
33 | 38 | app = wsgi.SharedDataMiddleware(null_application, { |
34 | 39 | '/': path.join(path.dirname(__file__), 'res'), |
35 | 40 | '/sources': path.join(path.dirname(__file__), 'res'), |
36 | '/pkg': ('werkzeug.debug', 'shared') | |
41 | '/pkg': ('werkzeug.debug', 'shared'), | |
42 | '/foo': test_dir | |
37 | 43 | }) |
38 | 44 | |
39 | for p in '/test.txt', '/sources/test.txt': | |
45 | for p in '/test.txt', '/sources/test.txt', '/foo/äöü': | |
40 | 46 | app_iter, status, headers = run_wsgi_app(app, create_environ(p)) |
41 | 47 | self.assert_equal(status, '200 OK') |
42 | 48 | with closing(app_iter) as app_iter: |
53 | 59 | app, create_environ('/missing')) |
54 | 60 | self.assert_equal(status, '404 NOT FOUND') |
55 | 61 | self.assert_equal(b''.join(app_iter).strip(), b'NOT FOUND') |
62 | ||
56 | 63 | |
57 | 64 | def test_get_host(self): |
58 | 65 | env = {'HTTP_X_FORWARDED_HOST': 'example.org', |
377 | 377 | :param charset: the charset to be used. |
378 | 378 | :param safe: an optional sequence of safe characters. |
379 | 379 | """ |
380 | if not isinstance(string, (text_type, bytes, bytearray)): | |
381 | string = text_type(string) | |
380 | 382 | if isinstance(string, text_type): |
381 | 383 | string = string.encode(charset, errors) |
382 | 384 | if isinstance(safe, text_type): |
387 | 389 | if char in safe: |
388 | 390 | rv.append(char) |
389 | 391 | else: |
390 | rv.extend(('%%%X' % char).encode('ascii')) | |
392 | rv.extend(('%%%02X' % char).encode('ascii')) | |
391 | 393 | return to_native(bytes(rv)) |
392 | 394 | |
393 | 395 |
20 | 20 | |
21 | 21 | from werkzeug._compat import iteritems, text_type, string_types, \ |
22 | 22 | implements_iterator, make_literal_wrapper, to_unicode, to_bytes, \ |
23 | wsgi_get_bytes, try_coerce_native | |
23 | wsgi_get_bytes, try_coerce_native, PY2 | |
24 | 24 | from werkzeug._internal import _empty_stream, _encode_idna |
25 | 25 | from werkzeug.http import is_resource_modified, http_date |
26 | 26 | from werkzeug.urls import uri_to_iri, url_quote, url_parse, url_join |
543 | 543 | return loader |
544 | 544 | |
545 | 545 | def generate_etag(self, mtime, file_size, real_filename): |
546 | if not isinstance(real_filename, bytes): | |
547 | real_filename = real_filename.encode(sys.getfilesystemencoding()) | |
546 | 548 | return 'wzsdm-%d-%s-%s' % ( |
547 | 549 | mktime(mtime.timetuple()), |
548 | 550 | file_size, |
549 | adler32(real_filename.encode(sys.getfilesystemencoding())) & 0xffffffff | |
551 | adler32(real_filename) & 0xffffffff | |
550 | 552 | ) |
551 | 553 | |
552 | 554 | def __call__(self, environ, start_response): |
555 | cleaned_path = get_path_info(environ) | |
556 | if PY2: | |
557 | cleaned_path = cleaned_path.encode(sys.getfilesystemencoding()) | |
553 | 558 | # sanitize the path for non unix systems |
554 | cleaned_path = environ.get('PATH_INFO', '').strip('/') | |
559 | cleaned_path = cleaned_path.strip('/') | |
555 | 560 | for sep in os.sep, os.altsep: |
556 | 561 | if sep and sep != '/': |
557 | 562 | cleaned_path = cleaned_path.replace(sep, '/') |
945 | 950 | from werkzeug.exceptions import ClientDisconnected |
946 | 951 | raise ClientDisconnected() |
947 | 952 | |
948 | def exhaust(self, chunk_size=1024 * 16): | |
953 | def exhaust(self, chunk_size=1024 * 64): | |
949 | 954 | """Exhaust the stream. This consumes all the data left until the |
950 | 955 | limit is reached. |
951 | 956 |